r22852: merge fixes for CVE-2007-2446 and CVE-2007-2447 to all branches
[ira/wip.git] / source3 / lib / util_str.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    
5    Copyright (C) Andrew Tridgell 1992-2001
6    Copyright (C) Simo Sorce      2001-2002
7    Copyright (C) Martin Pool     2003
8    Copyright (C) James Peach     2006
9    
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)
431 {
432         buf += strlen(buf) + 1;
433         return(buf);
434 }
435
436 /**
437  Skip past a string in a buffer. Buffer may not be
438  null terminated. end_ptr points to the first byte after
439  then end of the buffer.
440 **/
441
442 char *skip_string(const char *base, size_t len, char *buf)
443 {
444         const char *end_ptr = base + len;
445
446         if (end_ptr < base || !base || !buf || buf >= end_ptr) {
447                 return NULL;
448         }
449
450         /* Skip the string */
451         while (*buf) {
452                 buf++;
453                 if (buf >= end_ptr) {
454                         return NULL;
455                 }
456         }
457         /* Skip the '\0' */
458         buf++;
459         return buf;
460 }
461
462 /**
463  Count the number of characters in a string. Normally this will
464  be the same as the number of bytes in a string for single byte strings,
465  but will be different for multibyte.
466 **/
467
468 size_t str_charnum(const char *s)
469 {
470         uint16 tmpbuf2[sizeof(pstring)];
471         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
472         return strlen_w(tmpbuf2);
473 }
474
475 /**
476  Count the number of characters in a string. Normally this will
477  be the same as the number of bytes in a string for single byte strings,
478  but will be different for multibyte.
479 **/
480
481 size_t str_ascii_charnum(const char *s)
482 {
483         pstring tmpbuf2;
484         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
485         return strlen(tmpbuf2);
486 }
487
488 BOOL trim_char(char *s,char cfront,char cback)
489 {
490         BOOL ret = False;
491         char *ep;
492         char *fp = s;
493
494         /* Ignore null or empty strings. */
495         if (!s || (s[0] == '\0'))
496                 return False;
497
498         if (cfront) {
499                 while (*fp && *fp == cfront)
500                         fp++;
501                 if (!*fp) {
502                         /* We ate the string. */
503                         s[0] = '\0';
504                         return True;
505                 }
506                 if (fp != s)
507                         ret = True;
508         }
509
510         ep = fp + strlen(fp) - 1;
511         if (cback) {
512                 /* Attempt ascii only. Bail for mb strings. */
513                 while ((ep >= fp) && (*ep == cback)) {
514                         ret = True;
515                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
516                                 /* Could be mb... bail back to tim_string. */
517                                 char fs[2], bs[2];
518                                 if (cfront) {
519                                         fs[0] = cfront;
520                                         fs[1] = '\0';
521                                 }
522                                 bs[0] = cback;
523                                 bs[1] = '\0';
524                                 return trim_string(s, cfront ? fs : NULL, bs);
525                         } else {
526                                 ep--;
527                         }
528                 }
529                 if (ep < fp) {
530                         /* We ate the string. */
531                         s[0] = '\0';
532                         return True;
533                 }
534         }
535
536         ep[1] = '\0';
537         memmove(s, fp, ep-fp+2);
538         return ret;
539 }
540
541 /**
542  Trim the specified elements off the front and back of a string.
543 **/
544
545 BOOL trim_string(char *s,const char *front,const char *back)
546 {
547         BOOL ret = False;
548         size_t front_len;
549         size_t back_len;
550         size_t len;
551
552         /* Ignore null or empty strings. */
553         if (!s || (s[0] == '\0'))
554                 return False;
555
556         front_len       = front? strlen(front) : 0;
557         back_len        = back? strlen(back) : 0;
558
559         len = strlen(s);
560
561         if (front_len) {
562                 while (len && strncmp(s, front, front_len)==0) {
563                         /* Must use memmove here as src & dest can
564                          * easily overlap. Found by valgrind. JRA. */
565                         memmove(s, s+front_len, (len-front_len)+1);
566                         len -= front_len;
567                         ret=True;
568                 }
569         }
570         
571         if (back_len) {
572                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
573                         s[len-back_len]='\0';
574                         len -= back_len;
575                         ret=True;
576                 }
577         }
578         return ret;
579 }
580
581 /**
582  Does a string have any uppercase chars in it?
583 **/
584
585 BOOL strhasupper(const char *s)
586 {
587         smb_ucs2_t *ptr;
588         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
589         for(ptr=tmpbuf;*ptr;ptr++)
590                 if(isupper_w(*ptr))
591                         return True;
592         return(False);
593 }
594
595 /**
596  Does a string have any lowercase chars in it?
597 **/
598
599 BOOL strhaslower(const char *s)
600 {
601         smb_ucs2_t *ptr;
602         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
603         for(ptr=tmpbuf;*ptr;ptr++)
604                 if(islower_w(*ptr))
605                         return True;
606         return(False);
607 }
608
609 /**
610  Find the number of 'c' chars in a string
611 **/
612
613 size_t count_chars(const char *s,char c)
614 {
615         smb_ucs2_t *ptr;
616         int count;
617         smb_ucs2_t *alloc_tmpbuf = NULL;
618
619         if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
620                 return 0;
621         }
622
623         for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
624                 if(*ptr==UCS2_CHAR(c))
625                         count++;
626
627         SAFE_FREE(alloc_tmpbuf);
628         return(count);
629 }
630
631 /**
632  Safe string copy into a known length string. maxlength does not
633  include the terminating zero.
634 **/
635
636 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
637 {
638         size_t len;
639
640         if (!dest) {
641                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
642                 return NULL;
643         }
644
645 #ifdef DEVELOPER
646         clobber_region(fn,line,dest, maxlength+1);
647 #endif
648
649         if (!src) {
650                 *dest = 0;
651                 return dest;
652         }  
653
654         len = strnlen(src, maxlength+1);
655
656         if (len > maxlength) {
657                 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
658                          (unsigned long)(len-maxlength), (unsigned long)len, 
659                          (unsigned long)maxlength, src));
660                 len = maxlength;
661         }
662       
663         memmove(dest, src, len);
664         dest[len] = 0;
665         return dest;
666 }  
667
668 /**
669  Safe string cat into a string. maxlength does not
670  include the terminating zero.
671 **/
672 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
673 {
674         size_t src_len, dest_len;
675
676         if (!dest) {
677                 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
678                 return NULL;
679         }
680
681         if (!src)
682                 return dest;
683         
684         src_len = strnlen(src, maxlength + 1);
685         dest_len = strnlen(dest, maxlength + 1);
686
687 #ifdef DEVELOPER
688         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
689 #endif
690
691         if (src_len + dest_len > maxlength) {
692                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
693                          (int)(src_len + dest_len - maxlength), src));
694                 if (maxlength > dest_len) {
695                         memcpy(&dest[dest_len], src, maxlength - dest_len);
696                 }
697                 dest[maxlength] = 0;
698                 return NULL;
699         }
700
701         memcpy(&dest[dest_len], src, src_len);
702         dest[dest_len + src_len] = 0;
703         return dest;
704 }
705
706 /**
707  Paranoid strcpy into a buffer of given length (includes terminating
708  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
709  and replaces with '_'. Deliberately does *NOT* check for multibyte
710  characters. Don't change it !
711 **/
712 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
713 {
714         size_t len, i;
715
716 #ifdef DEVELOPER
717         clobber_region(fn, line, dest, maxlength);
718 #endif
719
720         if (!dest) {
721                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
722                 return NULL;
723         }
724
725         if (!src) {
726                 *dest = 0;
727                 return dest;
728         }  
729
730         len = strlen(src);
731         if (len >= maxlength)
732                 len = maxlength - 1;
733
734         if (!other_safe_chars)
735                 other_safe_chars = "";
736
737         for(i = 0; i < len; i++) {
738                 int val = (src[i] & 0xff);
739                 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
740                         dest[i] = src[i];
741                 else
742                         dest[i] = '_';
743         }
744
745         dest[i] = '\0';
746
747         return dest;
748 }
749
750 /**
751  Like strncpy but always null terminates. Make sure there is room!
752  The variable n should always be one less than the available size.
753 **/
754 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
755 {
756         char *d = dest;
757
758 #ifdef DEVELOPER
759         clobber_region(fn, line, dest, n+1);
760 #endif
761
762         if (!dest) {
763                 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
764                 return(NULL);
765         }
766
767         if (!src) {
768                 *dest = 0;
769                 return(dest);
770         }
771         
772         while (n-- && (*d = *src)) {
773                 d++;
774                 src++;
775         }
776
777         *d = 0;
778         return(dest);
779 }
780
781 #if 0
782 /**
783  Like strncpy but copies up to the character marker.  always null terminates.
784  returns a pointer to the character marker in the source string (src).
785 **/
786
787 static char *strncpyn(char *dest, const char *src, size_t n, char c)
788 {
789         char *p;
790         size_t str_len;
791
792 #ifdef DEVELOPER
793         clobber_region(dest, n+1);
794 #endif
795         p = strchr_m(src, c);
796         if (p == NULL) {
797                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
798                 return NULL;
799         }
800
801         str_len = PTR_DIFF(p, src);
802         strncpy(dest, src, MIN(n, str_len));
803         dest[str_len] = '\0';
804
805         return p;
806 }
807 #endif
808
809 /**
810  Routine to get hex characters and turn them into a 16 byte array.
811  the array can be variable length, and any non-hex-numeric
812  characters are skipped.  "0xnn" or "0Xnn" is specially catered
813  for.
814
815  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
816
817 **/
818
819 size_t strhex_to_str(char *p, size_t len, const char *strhex)
820 {
821         size_t i;
822         size_t num_chars = 0;
823         unsigned char   lonybble, hinybble;
824         const char     *hexchars = "0123456789ABCDEF";
825         char           *p1 = NULL, *p2 = NULL;
826
827         for (i = 0; i < len && strhex[i] != 0; i++) {
828                 if (strnequal(hexchars, "0x", 2)) {
829                         i++; /* skip two chars */
830                         continue;
831                 }
832
833                 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
834                         break;
835
836                 i++; /* next hex digit */
837
838                 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
839                         break;
840
841                 /* get the two nybbles */
842                 hinybble = PTR_DIFF(p1, hexchars);
843                 lonybble = PTR_DIFF(p2, hexchars);
844
845                 p[num_chars] = (hinybble << 4) | lonybble;
846                 num_chars++;
847
848                 p1 = NULL;
849                 p2 = NULL;
850         }
851         return num_chars;
852 }
853
854 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
855 {
856         DATA_BLOB ret_blob;
857
858         if (mem_ctx != NULL)
859                 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
860         else
861                 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
862
863         ret_blob.length = strhex_to_str((char*)ret_blob.data,   
864                                         strlen(strhex), 
865                                         strhex);
866
867         return ret_blob;
868 }
869
870 /**
871  * Routine to print a buffer as HEX digits, into an allocated string.
872  */
873
874 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
875 {
876         int i;
877         char *hex_buffer;
878
879         hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
880
881         for (i = 0; i < len; i++)
882                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
883
884         return hex_buffer;
885 }
886
887 /**
888  Check if a string is part of a list.
889 **/
890
891 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
892 {
893         pstring tok;
894         const char *p=list;
895
896         if (!list)
897                 return(False);
898
899         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
900                 if (casesensitive) {
901                         if (strcmp(tok,s) == 0)
902                                 return(True);
903                 } else {
904                         if (StrCaseCmp(tok,s) == 0)
905                                 return(True);
906                 }
907         }
908         return(False);
909 }
910
911 /* this is used to prevent lots of mallocs of size 1 */
912 static const char *null_string = "";
913
914 /**
915  Set a string value, allocing the space for the string
916 **/
917
918 static BOOL string_init(char **dest,const char *src)
919 {
920         size_t l;
921
922         if (!src)     
923                 src = "";
924
925         l = strlen(src);
926
927         if (l == 0) {
928                 *dest = CONST_DISCARD(char*, null_string);
929         } else {
930                 (*dest) = SMB_STRDUP(src);
931                 if ((*dest) == NULL) {
932                         DEBUG(0,("Out of memory in string_init\n"));
933                         return False;
934                 }
935         }
936         return(True);
937 }
938
939 /**
940  Free a string value.
941 **/
942
943 void string_free(char **s)
944 {
945         if (!s || !(*s))
946                 return;
947         if (*s == null_string)
948                 *s = NULL;
949         SAFE_FREE(*s);
950 }
951
952 /**
953  Set a string value, deallocating any existing space, and allocing the space
954  for the string
955 **/
956
957 BOOL string_set(char **dest,const char *src)
958 {
959         string_free(dest);
960         return(string_init(dest,src));
961 }
962
963 /**
964  Substitute a string for a pattern in another string. Make sure there is 
965  enough room!
966
967  This routine looks for pattern in s and replaces it with 
968  insert. It may do multiple replacements or just one.
969
970  Any of " ; ' $ or ` in the insert string are replaced with _
971  if len==0 then the string cannot be extended. This is different from the old
972  use of len==0 which was for no length checks to be done.
973 **/
974
975 void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
976                  BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
977 {
978         char *p;
979         ssize_t ls,lp,li, i;
980
981         if (!insert || !pattern || !*pattern || !s)
982                 return;
983
984         ls = (ssize_t)strlen(s);
985         lp = (ssize_t)strlen(pattern);
986         li = (ssize_t)strlen(insert);
987
988         if (len == 0)
989                 len = ls + 1; /* len is number of *bytes* */
990
991         while (lp <= ls && (p = strstr_m(s,pattern))) {
992                 if (ls + (li-lp) >= len) {
993                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
994                                  (int)(ls + (li-lp) - len),
995                                  pattern, (int)len));
996                         break;
997                 }
998                 if (li != lp) {
999                         memmove(p+li,p+lp,strlen(p+lp)+1);
1000                 }
1001                 for (i=0;i<li;i++) {
1002                         switch (insert[i]) {
1003                         case '`':
1004                         case '"':
1005                         case '\'':
1006                         case ';':
1007                         case '$':
1008                                 /* allow a trailing $ (as in machine accounts) */
1009                                 if (allow_trailing_dollar && (i == li - 1 )) {
1010                                         p[i] = insert[i];
1011                                         break;
1012                                 }
1013                         case '%':
1014                         case '\r':
1015                         case '\n':
1016                                 if ( remove_unsafe_characters ) {
1017                                         p[i] = '_';
1018                                         /* yes this break should be here since we want to 
1019                                            fall throw if not replacing unsafe chars */
1020                                         break;
1021                                 }
1022                         default:
1023                                 p[i] = insert[i];
1024                         }
1025                 }
1026                 s = p + li;
1027                 ls += (li-lp);
1028
1029                 if (replace_once)
1030                         break;
1031         }
1032 }
1033
1034 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
1035 {
1036         string_sub2( s, pattern, insert, len, True, True, False );
1037 }
1038
1039 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
1040 {
1041         string_sub2( s, pattern, insert, len, True, False, False );
1042 }
1043
1044 void fstring_sub(char *s,const char *pattern,const char *insert)
1045 {
1046         string_sub(s, pattern, insert, sizeof(fstring));
1047 }
1048
1049 void pstring_sub(char *s,const char *pattern,const char *insert)
1050 {
1051         string_sub(s, pattern, insert, sizeof(pstring));
1052 }
1053
1054 /**
1055  Similar to string_sub, but it will accept only allocated strings
1056  and may realloc them so pay attention at what you pass on no
1057  pointers inside strings, no pstrings or const may be passed
1058  as string.
1059 **/
1060
1061 char *realloc_string_sub(char *string, const char *pattern,
1062                          const char *insert)
1063 {
1064         char *p, *in;
1065         char *s;
1066         ssize_t ls,lp,li,ld, i;
1067
1068         if (!insert || !pattern || !*pattern || !string || !*string)
1069                 return NULL;
1070
1071         s = string;
1072
1073         in = SMB_STRDUP(insert);
1074         if (!in) {
1075                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1076                 return NULL;
1077         }
1078         ls = (ssize_t)strlen(s);
1079         lp = (ssize_t)strlen(pattern);
1080         li = (ssize_t)strlen(insert);
1081         ld = li - lp;
1082         for (i=0;i<li;i++) {
1083                 switch (in[i]) {
1084                         case '`':
1085                         case '"':
1086                         case '\'':
1087                         case ';':
1088                         case '$':
1089                         case '%':
1090                         case '\r':
1091                         case '\n':
1092                                 in[i] = '_';
1093                         default:
1094                                 /* ok */
1095                                 break;
1096                 }
1097         }
1098         
1099         while ((p = strstr_m(s,pattern))) {
1100                 if (ld > 0) {
1101                         int offset = PTR_DIFF(s,string);
1102                         string = (char *)SMB_REALLOC(string, ls + ld + 1);
1103                         if (!string) {
1104                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1105                                 SAFE_FREE(in);
1106                                 return NULL;
1107                         }
1108                         p = string + offset + (p - s);
1109                 }
1110                 if (li != lp) {
1111                         memmove(p+li,p+lp,strlen(p+lp)+1);
1112                 }
1113                 memcpy(p, in, li);
1114                 s = p + li;
1115                 ls += ld;
1116         }
1117         SAFE_FREE(in);
1118         return string;
1119 }
1120
1121 /* Same as string_sub, but returns a talloc'ed string */
1122
1123 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1124                         const char *pattern, const char *insert)
1125 {
1126         char *p, *in;
1127         char *s;
1128         char *string;
1129         ssize_t ls,lp,li,ld, i;
1130
1131         if (!insert || !pattern || !*pattern || !src || !*src)
1132                 return NULL;
1133
1134         string = talloc_strdup(mem_ctx, src);
1135         if (string == NULL) {
1136                 DEBUG(0, ("talloc_strdup failed\n"));
1137                 return NULL;
1138         }
1139
1140         s = string;
1141
1142         in = SMB_STRDUP(insert);
1143         if (!in) {
1144                 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1145                 return NULL;
1146         }
1147         ls = (ssize_t)strlen(s);
1148         lp = (ssize_t)strlen(pattern);
1149         li = (ssize_t)strlen(insert);
1150         ld = li - lp;
1151         for (i=0;i<li;i++) {
1152                 switch (in[i]) {
1153                         case '`':
1154                         case '"':
1155                         case '\'':
1156                         case ';':
1157                         case '$':
1158                         case '%':
1159                         case '\r':
1160                         case '\n':
1161                                 in[i] = '_';
1162                         default:
1163                                 /* ok */
1164                                 break;
1165                 }
1166         }
1167         
1168         while ((p = strstr_m(s,pattern))) {
1169                 if (ld > 0) {
1170                         int offset = PTR_DIFF(s,string);
1171                         string = (char *)TALLOC_REALLOC(mem_ctx, string,
1172                                                         ls + ld + 1);
1173                         if (!string) {
1174                                 DEBUG(0, ("talloc_string_sub: out of "
1175                                           "memory!\n"));
1176                                 SAFE_FREE(in);
1177                                 return NULL;
1178                         }
1179                         p = string + offset + (p - s);
1180                 }
1181                 if (li != lp) {
1182                         memmove(p+li,p+lp,strlen(p+lp)+1);
1183                 }
1184                 memcpy(p, in, li);
1185                 s = p + li;
1186                 ls += ld;
1187         }
1188         SAFE_FREE(in);
1189         return string;
1190 }
1191
1192 /**
1193  Similar to string_sub() but allows for any character to be substituted. 
1194  Use with caution!
1195  if len==0 then the string cannot be extended. This is different from the old
1196  use of len==0 which was for no length checks to be done.
1197 **/
1198
1199 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1200 {
1201         char *p;
1202         ssize_t ls,lp,li;
1203
1204         if (!insert || !pattern || !s)
1205                 return;
1206
1207         ls = (ssize_t)strlen(s);
1208         lp = (ssize_t)strlen(pattern);
1209         li = (ssize_t)strlen(insert);
1210
1211         if (!*pattern)
1212                 return;
1213         
1214         if (len == 0)
1215                 len = ls + 1; /* len is number of *bytes* */
1216         
1217         while (lp <= ls && (p = strstr_m(s,pattern))) {
1218                 if (ls + (li-lp) >= len) {
1219                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1220                                  (int)(ls + (li-lp) - len),
1221                                  pattern, (int)len));
1222                         break;
1223                 }
1224                 if (li != lp) {
1225                         memmove(p+li,p+lp,strlen(p+lp)+1);
1226                 }
1227                 memcpy(p, insert, li);
1228                 s = p + li;
1229                 ls += (li-lp);
1230         }
1231 }
1232
1233 /**
1234  Similar to all_string_sub but for unicode strings.
1235  Return a new allocated unicode string.
1236  similar to string_sub() but allows for any character to be substituted.
1237  Use with caution!
1238 **/
1239
1240 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1241                                 const smb_ucs2_t *insert)
1242 {
1243         smb_ucs2_t *r, *rp;
1244         const smb_ucs2_t *sp;
1245         size_t  lr, lp, li, lt;
1246
1247         if (!insert || !pattern || !*pattern || !s)
1248                 return NULL;
1249
1250         lt = (size_t)strlen_w(s);
1251         lp = (size_t)strlen_w(pattern);
1252         li = (size_t)strlen_w(insert);
1253
1254         if (li > lp) {
1255                 const smb_ucs2_t *st = s;
1256                 int ld = li - lp;
1257                 while ((sp = strstr_w(st, pattern))) {
1258                         st = sp + lp;
1259                         lt += ld;
1260                 }
1261         }
1262
1263         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1264         if (!r) {
1265                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1266                 return NULL;
1267         }
1268
1269         while ((sp = strstr_w(s, pattern))) {
1270                 memcpy(rp, s, (sp - s));
1271                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1272                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1273                 s = sp + lp;
1274                 rp += li;
1275         }
1276         lr = ((rp - r) / sizeof(smb_ucs2_t));
1277         if (lr < lt) {
1278                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1279                 rp += (lt - lr);
1280         }
1281         *rp = 0;
1282
1283         return r;
1284 }
1285
1286 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1287                                              const char *insert)
1288 {
1289         wpstring p, i;
1290
1291         if (!insert || !pattern || !s)
1292                 return NULL;
1293         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1294         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1295         return all_string_sub_w(s, p, i);
1296 }
1297
1298 #if 0
1299 /**
1300  Splits out the front and back at a separator.
1301 **/
1302
1303 static void split_at_last_component(char *path, char *front, char sep, char *back)
1304 {
1305         char *p = strrchr_m(path, sep);
1306
1307         if (p != NULL)
1308                 *p = 0;
1309
1310         if (front != NULL)
1311                 pstrcpy(front, path);
1312
1313         if (p != NULL) {
1314                 if (back != NULL)
1315                         pstrcpy(back, p+1);
1316                 *p = '\\';
1317         } else {
1318                 if (back != NULL)
1319                         back[0] = 0;
1320         }
1321 }
1322 #endif
1323
1324 /**
1325  Write an octal as a string.
1326 **/
1327
1328 const char *octal_string(int i)
1329 {
1330         static char ret[64];
1331         if (i == -1)
1332                 return "-1";
1333         slprintf(ret, sizeof(ret)-1, "0%o", i);
1334         return ret;
1335 }
1336
1337
1338 /**
1339  Truncate a string at a specified length.
1340 **/
1341
1342 char *string_truncate(char *s, unsigned int length)
1343 {
1344         if (s && strlen(s) > length)
1345                 s[length] = 0;
1346         return s;
1347 }
1348
1349 /**
1350  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1351  We convert via ucs2 for now.
1352 **/
1353
1354 char *strchr_m(const char *src, char c)
1355 {
1356         wpstring ws;
1357         pstring s2;
1358         smb_ucs2_t *p;
1359         const char *s;
1360
1361         /* characters below 0x3F are guaranteed to not appear in
1362            non-initial position in multi-byte charsets */
1363         if ((c & 0xC0) == 0) {
1364                 return strchr(src, c);
1365         }
1366
1367         /* this is quite a common operation, so we want it to be
1368            fast. We optimise for the ascii case, knowing that all our
1369            supported multi-byte character sets are ascii-compatible
1370            (ie. they match for the first 128 chars) */
1371
1372         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1373                 if (*s == c)
1374                         return (char *)s;
1375         }
1376
1377         if (!*s)
1378                 return NULL;
1379
1380 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1381         /* With compose characters we must restart from the beginning. JRA. */
1382         s = src;
1383 #endif
1384
1385         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1386         p = strchr_w(ws, UCS2_CHAR(c));
1387         if (!p)
1388                 return NULL;
1389         *p = 0;
1390         pull_ucs2_pstring(s2, ws);
1391         return (char *)(s+strlen(s2));
1392 }
1393
1394 char *strrchr_m(const char *s, char c)
1395 {
1396         /* characters below 0x3F are guaranteed to not appear in
1397            non-initial position in multi-byte charsets */
1398         if ((c & 0xC0) == 0) {
1399                 return strrchr(s, c);
1400         }
1401
1402         /* this is quite a common operation, so we want it to be
1403            fast. We optimise for the ascii case, knowing that all our
1404            supported multi-byte character sets are ascii-compatible
1405            (ie. they match for the first 128 chars). Also, in Samba
1406            we only search for ascii characters in 'c' and that
1407            in all mb character sets with a compound character
1408            containing c, if 'c' is not a match at position
1409            p, then p[-1] > 0x7f. JRA. */
1410
1411         {
1412                 size_t len = strlen(s);
1413                 const char *cp = s;
1414                 BOOL got_mb = False;
1415
1416                 if (len == 0)
1417                         return NULL;
1418                 cp += (len - 1);
1419                 do {
1420                         if (c == *cp) {
1421                                 /* Could be a match. Part of a multibyte ? */
1422                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1423                                         /* Yep - go slow :-( */
1424                                         got_mb = True;
1425                                         break;
1426                                 }
1427                                 /* No - we have a match ! */
1428                                 return (char *)cp;
1429                         }
1430                 } while (cp-- != s);
1431                 if (!got_mb)
1432                         return NULL;
1433         }
1434
1435         /* String contained a non-ascii char. Slow path. */
1436         {
1437                 wpstring ws;
1438                 pstring s2;
1439                 smb_ucs2_t *p;
1440
1441                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1442                 p = strrchr_w(ws, UCS2_CHAR(c));
1443                 if (!p)
1444                         return NULL;
1445                 *p = 0;
1446                 pull_ucs2_pstring(s2, ws);
1447                 return (char *)(s+strlen(s2));
1448         }
1449 }
1450
1451 /***********************************************************************
1452  Return the equivalent of doing strrchr 'n' times - always going
1453  backwards.
1454 ***********************************************************************/
1455
1456 char *strnrchr_m(const char *s, char c, unsigned int n)
1457 {
1458         wpstring ws;
1459         pstring s2;
1460         smb_ucs2_t *p;
1461
1462         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1463         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1464         if (!p)
1465                 return NULL;
1466         *p = 0;
1467         pull_ucs2_pstring(s2, ws);
1468         return (char *)(s+strlen(s2));
1469 }
1470
1471 /***********************************************************************
1472  strstr_m - We convert via ucs2 for now.
1473 ***********************************************************************/
1474
1475 char *strstr_m(const char *src, const char *findstr)
1476 {
1477         smb_ucs2_t *p;
1478         smb_ucs2_t *src_w, *find_w;
1479         const char *s;
1480         char *s2;
1481         char *retp;
1482
1483         size_t findstr_len = 0;
1484
1485         /* for correctness */
1486         if (!findstr[0]) {
1487                 return (char*)src;
1488         }
1489
1490         /* Samba does single character findstr calls a *lot*. */
1491         if (findstr[1] == '\0')
1492                 return strchr_m(src, *findstr);
1493
1494         /* We optimise for the ascii case, knowing that all our
1495            supported multi-byte character sets are ascii-compatible
1496            (ie. they match for the first 128 chars) */
1497
1498         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1499                 if (*s == *findstr) {
1500                         if (!findstr_len) 
1501                                 findstr_len = strlen(findstr);
1502
1503                         if (strncmp(s, findstr, findstr_len) == 0) {
1504                                 return (char *)s;
1505                         }
1506                 }
1507         }
1508
1509         if (!*s)
1510                 return NULL;
1511
1512 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1513         /* 'make check' fails unless we do this */
1514
1515         /* With compose characters we must restart from the beginning. JRA. */
1516         s = src;
1517 #endif
1518
1519         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1520                 DEBUG(0,("strstr_m: src malloc fail\n"));
1521                 return NULL;
1522         }
1523         
1524         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1525                 SAFE_FREE(src_w);
1526                 DEBUG(0,("strstr_m: find malloc fail\n"));
1527                 return NULL;
1528         }
1529
1530         p = strstr_w(src_w, find_w);
1531
1532         if (!p) {
1533                 SAFE_FREE(src_w);
1534                 SAFE_FREE(find_w);
1535                 return NULL;
1536         }
1537         
1538         *p = 0;
1539         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1540                 SAFE_FREE(src_w);
1541                 SAFE_FREE(find_w);
1542                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1543                 return NULL;
1544         }
1545         retp = (char *)(s+strlen(s2));
1546         SAFE_FREE(src_w);
1547         SAFE_FREE(find_w);
1548         SAFE_FREE(s2);
1549         return retp;
1550 }
1551
1552 /**
1553  Convert a string to lower case.
1554 **/
1555
1556 void strlower_m(char *s)
1557 {
1558         size_t len;
1559         int errno_save;
1560
1561         /* this is quite a common operation, so we want it to be
1562            fast. We optimise for the ascii case, knowing that all our
1563            supported multi-byte character sets are ascii-compatible
1564            (ie. they match for the first 128 chars) */
1565
1566         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1567                 *s = tolower_ascii((unsigned char)*s);
1568                 s++;
1569         }
1570
1571         if (!*s)
1572                 return;
1573
1574         /* I assume that lowercased string takes the same number of bytes
1575          * as source string even in UTF-8 encoding. (VIV) */
1576         len = strlen(s) + 1;
1577         errno_save = errno;
1578         errno = 0;
1579         unix_strlower(s,len,s,len);     
1580         /* Catch mb conversion errors that may not terminate. */
1581         if (errno)
1582                 s[len-1] = '\0';
1583         errno = errno_save;
1584 }
1585
1586 /**
1587  Convert a string to upper case.
1588 **/
1589
1590 void strupper_m(char *s)
1591 {
1592         size_t len;
1593         int errno_save;
1594
1595         /* this is quite a common operation, so we want it to be
1596            fast. We optimise for the ascii case, knowing that all our
1597            supported multi-byte character sets are ascii-compatible
1598            (ie. they match for the first 128 chars) */
1599
1600         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1601                 *s = toupper_ascii((unsigned char)*s);
1602                 s++;
1603         }
1604
1605         if (!*s)
1606                 return;
1607
1608         /* I assume that lowercased string takes the same number of bytes
1609          * as source string even in multibyte encoding. (VIV) */
1610         len = strlen(s) + 1;
1611         errno_save = errno;
1612         errno = 0;
1613         unix_strupper(s,len,s,len);     
1614         /* Catch mb conversion errors that may not terminate. */
1615         if (errno)
1616                 s[len-1] = '\0';
1617         errno = errno_save;
1618 }
1619
1620 /**
1621  Count the number of UCS2 characters in a string. Normally this will
1622  be the same as the number of bytes in a string for single byte strings,
1623  but will be different for multibyte.
1624 **/
1625
1626 size_t strlen_m(const char *s)
1627 {
1628         size_t count = 0;
1629
1630         if (!s) {
1631                 return 0;
1632         }
1633
1634         while (*s && !(((uint8_t)*s) & 0x80)) {
1635                 s++;
1636                 count++;
1637         }
1638
1639         if (!*s) {
1640                 return count;
1641         }
1642
1643         while (*s) {
1644                 size_t c_size;
1645                 codepoint_t c = next_codepoint(s, &c_size);
1646                 if (c < 0x10000) {
1647                         /* Unicode char fits into 16 bits. */
1648                         count += 1;
1649                 } else {
1650                         /* Double-width unicode char - 32 bits. */
1651                         count += 2;
1652                 }
1653                 s += c_size;
1654         }
1655
1656         return count;
1657 }
1658
1659 /**
1660  Count the number of UCS2 characters in a string including the null
1661  terminator.
1662 **/
1663
1664 size_t strlen_m_term(const char *s)
1665 {
1666         if (!s) {
1667                 return 0;
1668         }
1669         return strlen_m(s) + 1;
1670 }
1671
1672 /*
1673  * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1674  * if a string is there, include the terminator.
1675  */
1676
1677 size_t strlen_m_term_null(const char *s)
1678 {
1679         size_t len;
1680         if (!s) {
1681                 return 0;
1682         }
1683         len = strlen_m(s);
1684         if (len == 0) {
1685                 return 0;
1686         }
1687
1688         return len+1;
1689 }
1690 /**
1691  Return a RFC2254 binary string representation of a buffer.
1692  Used in LDAP filters.
1693  Caller must free.
1694 **/
1695
1696 char *binary_string_rfc2254(char *buf, int len)
1697 {
1698         char *s;
1699         int i, j;
1700         const char *hex = "0123456789ABCDEF";
1701         s = (char *)SMB_MALLOC(len * 3 + 1);
1702         if (!s)
1703                 return NULL;
1704         for (j=i=0;i<len;i++) {
1705                 s[j] = '\\';
1706                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1707                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1708                 j += 3;
1709         }
1710         s[j] = 0;
1711         return s;
1712 }
1713
1714 char *binary_string(char *buf, int len)
1715 {
1716         char *s;
1717         int i, j;
1718         const char *hex = "0123456789ABCDEF";
1719         s = (char *)SMB_MALLOC(len * 2 + 1);
1720         if (!s)
1721                 return NULL;
1722         for (j=i=0;i<len;i++) {
1723                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1724                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1725                 j += 2;
1726         }
1727         s[j] = 0;
1728         return s;
1729 }
1730 /**
1731  Just a typesafety wrapper for snprintf into a pstring.
1732 **/
1733
1734  int pstr_sprintf(pstring s, const char *fmt, ...)
1735 {
1736         va_list ap;
1737         int ret;
1738
1739         va_start(ap, fmt);
1740         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1741         va_end(ap);
1742         return ret;
1743 }
1744
1745
1746 /**
1747  Just a typesafety wrapper for snprintf into a fstring.
1748 **/
1749
1750 int fstr_sprintf(fstring s, const char *fmt, ...)
1751 {
1752         va_list ap;
1753         int ret;
1754
1755         va_start(ap, fmt);
1756         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1757         va_end(ap);
1758         return ret;
1759 }
1760
1761 /**
1762  List of Strings manipulation functions
1763 **/
1764
1765 #define S_LIST_ABS 16 /* List Allocation Block Size */
1766
1767 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1768 {
1769         char **list, **rlist;
1770         const char *str;
1771         char *s;
1772         int num, lsize;
1773         pstring tok;
1774         
1775         if (!string || !*string)
1776                 return NULL;
1777         if (mem_ctx) {
1778                 s = talloc_strdup(mem_ctx, string);
1779         } else {
1780                 s = SMB_STRDUP(string);
1781         }
1782         if (!s) {
1783                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1784                 return NULL;
1785         }
1786         if (!sep) sep = LIST_SEP;
1787         
1788         num = lsize = 0;
1789         list = NULL;
1790         
1791         str = s;
1792         while (next_token(&str, tok, sep, sizeof(tok))) {               
1793                 if (num == lsize) {
1794                         lsize += S_LIST_ABS;
1795                         if (mem_ctx) {
1796                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1797                         } else {
1798                                 /* We need to keep the old list on error so we can free the elements
1799                                    if the realloc fails. */
1800                                 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1801                         }
1802                         if (!rlist) {
1803                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1804                                 str_list_free(&list);
1805                                 if (mem_ctx) {
1806                                         TALLOC_FREE(s);
1807                                 } else {
1808                                         SAFE_FREE(s);
1809                                 }
1810                                 return NULL;
1811                         } else {
1812                                 list = rlist;
1813                         }
1814                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1815                 }
1816
1817                 if (mem_ctx) {
1818                         list[num] = talloc_strdup(mem_ctx, tok);
1819                 } else {
1820                         list[num] = SMB_STRDUP(tok);
1821                 }
1822                 
1823                 if (!list[num]) {
1824                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1825                         str_list_free(&list);
1826                         if (mem_ctx) {
1827                                 TALLOC_FREE(s);
1828                         } else {
1829                                 SAFE_FREE(s);
1830                         }
1831                         return NULL;
1832                 }
1833         
1834                 num++;  
1835         }
1836
1837         if (mem_ctx) {
1838                 TALLOC_FREE(s);
1839         } else {
1840                 SAFE_FREE(s);
1841         }
1842
1843         return list;
1844 }
1845
1846 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1847 {
1848         return str_list_make_internal(mem_ctx, string, sep);
1849 }
1850
1851 char **str_list_make(const char *string, const char *sep)
1852 {
1853         return str_list_make_internal(NULL, string, sep);
1854 }
1855
1856 BOOL str_list_copy(char ***dest, const char **src)
1857 {
1858         char **list, **rlist;
1859         int num, lsize;
1860         
1861         *dest = NULL;
1862         if (!src)
1863                 return False;
1864         
1865         num = lsize = 0;
1866         list = NULL;
1867                 
1868         while (src[num]) {
1869                 if (num == lsize) {
1870                         lsize += S_LIST_ABS;
1871                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1872                         if (!rlist) {
1873                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1874                                 str_list_free(&list);
1875                                 return False;
1876                         } else {
1877                                 list = rlist;
1878                         }
1879                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1880                 }
1881                 
1882                 list[num] = SMB_STRDUP(src[num]);
1883                 if (!list[num]) {
1884                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1885                         str_list_free(&list);
1886                         return False;
1887                 }
1888
1889                 num++;
1890         }
1891         
1892         *dest = list;
1893         return True;    
1894 }
1895
1896 /**
1897  * Return true if all the elements of the list match exactly.
1898  **/
1899 BOOL str_list_compare(char **list1, char **list2)
1900 {
1901         int num;
1902         
1903         if (!list1 || !list2)
1904                 return (list1 == list2); 
1905         
1906         for (num = 0; list1[num]; num++) {
1907                 if (!list2[num])
1908                         return False;
1909                 if (!strcsequal(list1[num], list2[num]))
1910                         return False;
1911         }
1912         if (list2[num])
1913                 return False; /* if list2 has more elements than list1 fail */
1914         
1915         return True;
1916 }
1917
1918 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1919 {
1920         char **tlist;
1921         
1922         if (!list || !*list)
1923                 return;
1924         tlist = *list;
1925         for(; *tlist; tlist++) {
1926                 if (mem_ctx) {
1927                         TALLOC_FREE(*tlist);
1928                 } else {
1929                         SAFE_FREE(*tlist);
1930                 }
1931         }
1932         if (mem_ctx) {
1933                 TALLOC_FREE(*tlist);
1934         } else {
1935                 SAFE_FREE(*list);
1936         }
1937 }
1938
1939 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1940 {
1941         str_list_free_internal(mem_ctx, list);
1942 }
1943
1944 void str_list_free(char ***list)
1945 {
1946         str_list_free_internal(NULL, list);
1947 }
1948
1949 /******************************************************************************
1950  *****************************************************************************/
1951
1952 int str_list_count( const char **list )
1953 {
1954         int i = 0;
1955
1956         if ( ! list )
1957                 return 0;
1958
1959         /* count the number of list members */
1960         
1961         for ( i=0; *list; i++, list++ );
1962         
1963         return i;
1964 }
1965
1966 /******************************************************************************
1967  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1968  for the work
1969  *****************************************************************************/
1970  
1971 BOOL str_list_sub_basic( char **list, const char *smb_name,
1972                          const char *domain_name )
1973 {
1974         char *s, *tmpstr;
1975         
1976         while ( *list ) {
1977                 s = *list;
1978                 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
1979                 if ( !tmpstr ) {
1980                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1981                         return False;
1982                 }
1983
1984                 SAFE_FREE(*list);
1985                 *list = tmpstr;
1986                         
1987                 list++;
1988         }
1989
1990         return True;
1991 }
1992
1993 /******************************************************************************
1994  substritute a specific pattern in a string list
1995  *****************************************************************************/
1996  
1997 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1998 {
1999         char *p, *s, *t;
2000         ssize_t ls, lp, li, ld, i, d;
2001
2002         if (!list)
2003                 return False;
2004         if (!pattern)
2005                 return False;
2006         if (!insert)
2007                 return False;
2008
2009         lp = (ssize_t)strlen(pattern);
2010         li = (ssize_t)strlen(insert);
2011         ld = li -lp;
2012                         
2013         while (*list) {
2014                 s = *list;
2015                 ls = (ssize_t)strlen(s);
2016
2017                 while ((p = strstr_m(s, pattern))) {
2018                         t = *list;
2019                         d = p -t;
2020                         if (ld) {
2021                                 t = (char *) SMB_MALLOC(ls +ld +1);
2022                                 if (!t) {
2023                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
2024                                         return False;
2025                                 }
2026                                 memcpy(t, *list, d);
2027                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
2028                                 SAFE_FREE(*list);
2029                                 *list = t;
2030                                 ls += ld;
2031                                 s = t +d +li;
2032                         }
2033                         
2034                         for (i = 0; i < li; i++) {
2035                                 switch (insert[i]) {
2036                                         case '`':
2037                                         case '"':
2038                                         case '\'':
2039                                         case ';':
2040                                         case '$':
2041                                         case '%':
2042                                         case '\r':
2043                                         case '\n':
2044                                                 t[d +i] = '_';
2045                                                 break;
2046                                         default:
2047                                                 t[d +i] = insert[i];
2048                                 }
2049                         }       
2050                 }
2051                 
2052                 
2053                 list++;
2054         }
2055         
2056         return True;
2057 }
2058
2059
2060 #define IPSTR_LIST_SEP  ","
2061 #define IPSTR_LIST_CHAR ','
2062
2063 /**
2064  * Add ip string representation to ipstr list. Used also
2065  * as part of @function ipstr_list_make
2066  *
2067  * @param ipstr_list pointer to string containing ip list;
2068  *        MUST BE already allocated and IS reallocated if necessary
2069  * @param ipstr_size pointer to current size of ipstr_list (might be changed
2070  *        as a result of reallocation)
2071  * @param ip IP address which is to be added to list
2072  * @return pointer to string appended with new ip and possibly
2073  *         reallocated to new length
2074  **/
2075
2076 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2077 {
2078         char* new_ipstr = NULL;
2079         
2080         /* arguments checking */
2081         if (!ipstr_list || !service) return NULL;
2082
2083         /* attempt to convert ip to a string and append colon separator to it */
2084         if (*ipstr_list) {
2085                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2086                         inet_ntoa(service->ip), service->port);
2087                 SAFE_FREE(*ipstr_list);
2088         } else {
2089                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2090         }
2091         *ipstr_list = new_ipstr;
2092         return *ipstr_list;
2093 }
2094
2095
2096 /**
2097  * Allocate and initialise an ipstr list using ip adresses
2098  * passed as arguments.
2099  *
2100  * @param ipstr_list pointer to string meant to be allocated and set
2101  * @param ip_list array of ip addresses to place in the list
2102  * @param ip_count number of addresses stored in ip_list
2103  * @return pointer to allocated ip string
2104  **/
2105  
2106 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2107 {
2108         int i;
2109         
2110         /* arguments checking */
2111         if (!ip_list || !ipstr_list) return 0;
2112
2113         *ipstr_list = NULL;
2114         
2115         /* process ip addresses given as arguments */
2116         for (i = 0; i < ip_count; i++)
2117                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2118         
2119         return (*ipstr_list);
2120 }
2121
2122
2123 /**
2124  * Parse given ip string list into array of ip addresses
2125  * (as ip_service structures)  
2126  *    e.g. 192.168.1.100:389,192.168.1.78, ...
2127  *
2128  * @param ipstr ip string list to be parsed 
2129  * @param ip_list pointer to array of ip addresses which is
2130  *        allocated by this function and must be freed by caller
2131  * @return number of succesfully parsed addresses
2132  **/
2133  
2134 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2135 {
2136         fstring token_str;
2137         size_t count;
2138         int i;
2139
2140         if (!ipstr_list || !ip_list) 
2141                 return 0;
2142         
2143         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2144         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2145                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2146                 return 0;
2147         }
2148         
2149         for ( i=0; 
2150                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
2151                 i++ ) 
2152         {
2153                 struct in_addr addr;
2154                 unsigned port = 0;      
2155                 char *p = strchr(token_str, ':');
2156                 
2157                 if (p) {
2158                         *p = 0;
2159                         port = atoi(p+1);
2160                 }
2161
2162                 /* convert single token to ip address */
2163                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2164                         break;
2165                                 
2166                 (*ip_list)[i].ip = addr;
2167                 (*ip_list)[i].port = port;
2168         }
2169         
2170         return count;
2171 }
2172
2173
2174 /**
2175  * Safely free ip string list
2176  *
2177  * @param ipstr_list ip string list to be freed
2178  **/
2179
2180 void ipstr_list_free(char* ipstr_list)
2181 {
2182         SAFE_FREE(ipstr_list);
2183 }
2184
2185
2186 /**
2187  Unescape a URL encoded string, in place.
2188 **/
2189
2190 void rfc1738_unescape(char *buf)
2191 {
2192         char *p=buf;
2193
2194         while (p && *p && (p=strchr_m(p,'%'))) {
2195                 int c1 = p[1];
2196                 int c2 = p[2];
2197
2198                 if (c1 >= '0' && c1 <= '9')
2199                         c1 = c1 - '0';
2200                 else if (c1 >= 'A' && c1 <= 'F')
2201                         c1 = 10 + c1 - 'A';
2202                 else if (c1 >= 'a' && c1 <= 'f')
2203                         c1 = 10 + c1 - 'a';
2204                 else {p++; continue;}
2205
2206                 if (c2 >= '0' && c2 <= '9')
2207                         c2 = c2 - '0';
2208                 else if (c2 >= 'A' && c2 <= 'F')
2209                         c2 = 10 + c2 - 'A';
2210                 else if (c2 >= 'a' && c2 <= 'f')
2211                         c2 = 10 + c2 - 'a';
2212                 else {p++; continue;}
2213                         
2214                 *p = (c1<<4) | c2;
2215
2216                 memmove(p+1, p+3, strlen(p+3)+1);
2217                 p++;
2218         }
2219 }
2220
2221 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2222
2223 /**
2224  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2225  **/
2226 DATA_BLOB base64_decode_data_blob(const char *s)
2227 {
2228         int bit_offset, byte_offset, idx, i, n;
2229         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2230         unsigned char *d = decoded.data;
2231         char *p;
2232
2233         n=i=0;
2234
2235         while (*s && (p=strchr_m(b64,*s))) {
2236                 idx = (int)(p - b64);
2237                 byte_offset = (i*6)/8;
2238                 bit_offset = (i*6)%8;
2239                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2240                 if (bit_offset < 3) {
2241                         d[byte_offset] |= (idx << (2-bit_offset));
2242                         n = byte_offset+1;
2243                 } else {
2244                         d[byte_offset] |= (idx >> (bit_offset-2));
2245                         d[byte_offset+1] = 0;
2246                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2247                         n = byte_offset+2;
2248                 }
2249                 s++; i++;
2250         }
2251
2252         if ((n > 0) && (*s == '=')) {
2253                 n -= 1;
2254         }
2255
2256         /* fix up length */
2257         decoded.length = n;
2258         return decoded;
2259 }
2260
2261 /**
2262  * Decode a base64 string in-place - wrapper for the above
2263  **/
2264 void base64_decode_inplace(char *s)
2265 {
2266         DATA_BLOB decoded = base64_decode_data_blob(s);
2267
2268         if ( decoded.length != 0 ) {
2269                 memcpy(s, decoded.data, decoded.length);
2270
2271                 /* null terminate */
2272                 s[decoded.length] = '\0';
2273         } else {
2274                 *s = '\0';
2275         }
2276
2277         data_blob_free(&decoded);
2278 }
2279
2280 /**
2281  * Encode a base64 string into a malloc()ed string caller to free.
2282  *
2283  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2284  **/
2285 char * base64_encode_data_blob(DATA_BLOB data)
2286 {
2287         int bits = 0;
2288         int char_count = 0;
2289         size_t out_cnt, len, output_len;
2290         char *result;
2291
2292         if (!data.length || !data.data)
2293                 return NULL;
2294
2295         out_cnt = 0;
2296         len = data.length;
2297         output_len = data.length * 2;
2298         result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2299
2300         while (len-- && out_cnt < (data.length * 2) - 5) {
2301                 int c = (unsigned char) *(data.data++);
2302                 bits += c;
2303                 char_count++;
2304                 if (char_count == 3) {
2305                         result[out_cnt++] = b64[bits >> 18];
2306                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2307                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2308             result[out_cnt++] = b64[bits & 0x3f];
2309             bits = 0;
2310             char_count = 0;
2311         } else {
2312             bits <<= 8;
2313         }
2314     }
2315     if (char_count != 0) {
2316         bits <<= 16 - (8 * char_count);
2317         result[out_cnt++] = b64[bits >> 18];
2318         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2319         if (char_count == 1) {
2320             result[out_cnt++] = '=';
2321             result[out_cnt++] = '=';
2322         } else {
2323             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2324             result[out_cnt++] = '=';
2325         }
2326     }
2327     result[out_cnt] = '\0';     /* terminate */
2328     return result;
2329 }
2330
2331 /* read a SMB_BIG_UINT from a string */
2332 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2333 {
2334
2335         SMB_BIG_UINT val = -1;
2336         const char *p = nptr;
2337         
2338         if (!p) {
2339                 if (entptr) {
2340                         *entptr = p;
2341                 }
2342                 return val;
2343         }
2344
2345         while (*p && isspace(*p))
2346                 p++;
2347
2348 #ifdef LARGE_SMB_OFF_T
2349         sscanf(p,"%llu",&val);  
2350 #else /* LARGE_SMB_OFF_T */
2351         sscanf(p,"%lu",&val);
2352 #endif /* LARGE_SMB_OFF_T */
2353         if (entptr) {
2354                 while (*p && isdigit(*p))
2355                         p++;
2356                 *entptr = p;
2357         }
2358
2359         return val;
2360 }
2361
2362 /* Convert a size specification to a count of bytes. We accept the following
2363  * suffixes:
2364  *          bytes if there is no suffix
2365  *      kK  kibibytes
2366  *      mM  mebibytes
2367  *      gG  gibibytes
2368  *      tT  tibibytes
2369  *      pP  whatever the ISO name for petabytes is
2370  *
2371  *  Returns 0 if the string can't be converted.
2372  */
2373 SMB_OFF_T conv_str_size(const char * str)
2374 {
2375         SMB_OFF_T lval;
2376         char * end;
2377
2378         if (str == NULL || *str == '\0') {
2379                 return 0;
2380         }
2381
2382 #ifdef HAVE_STRTOULL
2383         if (sizeof(SMB_OFF_T) == 8) {
2384             lval = strtoull(str, &end, 10 /* base */);
2385         } else {
2386             lval = strtoul(str, &end, 10 /* base */);
2387         }
2388 #else
2389         lval = strtoul(str, &end, 10 /* base */);
2390 #endif
2391
2392         if (end == NULL || end == str) {
2393                 return 0;
2394         }
2395
2396         if (*end) {
2397                 SMB_OFF_T lval_orig = lval;
2398
2399                 if (strwicmp(end, "K") == 0) {
2400                         lval *= (SMB_OFF_T)1024;
2401                 } else if (strwicmp(end, "M") == 0) {
2402                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2403                 } else if (strwicmp(end, "G") == 0) {
2404                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2405                                 (SMB_OFF_T)1024);
2406                 } else if (strwicmp(end, "T") == 0) {
2407                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2408                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2409                 } else if (strwicmp(end, "P") == 0) {
2410                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2411                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2412                                 (SMB_OFF_T)1024);
2413                 } else {
2414                         return 0;
2415                 }
2416
2417                 /* Primitive attempt to detect wrapping on platforms with
2418                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2419                  * a failure than some random number.
2420                  */
2421                 if (lval_orig <= lval) {
2422                         return 0;
2423                 }
2424         }
2425
2426         return lval;
2427 }
2428
2429 void string_append(char **left, const char *right)
2430 {
2431         int new_len = strlen(right) + 1;
2432
2433         if (*left == NULL) {
2434                 *left = (char *)SMB_MALLOC(new_len);
2435                 *left[0] = '\0';
2436         } else {
2437                 new_len += strlen(*left);
2438                 *left = (char *)SMB_REALLOC(*left, new_len);
2439         }
2440
2441         if (*left == NULL) {
2442                 return;
2443         }
2444
2445         safe_strcat(*left, right, new_len-1);
2446 }
2447
2448 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2449                          const char *str, const char ***strings,
2450                          int *num)
2451 {
2452         char *dup_str = talloc_strdup(mem_ctx, str);
2453
2454         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2455
2456         if ((*strings == NULL) || (dup_str == NULL)) {
2457                 *num = 0;
2458                 return False;
2459         }
2460
2461         (*strings)[*num] = dup_str;
2462         *num += 1;
2463         return True;
2464 }
2465
2466 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2467  * error checking in between. The indiation that something weird happened is
2468  * string==NULL */
2469
2470 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2471                     size_t *bufsize, const char *fmt, ...)
2472 {
2473         va_list ap;
2474         char *newstr;
2475         int ret;
2476         BOOL increased;
2477
2478         /* len<0 is an internal marker that something failed */
2479         if (*len < 0)
2480                 goto error;
2481
2482         if (*string == NULL) {
2483                 if (*bufsize == 0)
2484                         *bufsize = 128;
2485
2486                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2487                 if (*string == NULL)
2488                         goto error;
2489         }
2490
2491         va_start(ap, fmt);
2492         ret = vasprintf(&newstr, fmt, ap);
2493         va_end(ap);
2494
2495         if (ret < 0)
2496                 goto error;
2497
2498         increased = False;
2499
2500         while ((*len)+ret >= *bufsize) {
2501                 increased = True;
2502                 *bufsize *= 2;
2503                 if (*bufsize >= (1024*1024*256))
2504                         goto error;
2505         }
2506
2507         if (increased) {
2508                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2509                                                *bufsize);
2510                 if (*string == NULL) {
2511                         goto error;
2512                 }
2513         }
2514
2515         StrnCpy((*string)+(*len), newstr, ret);
2516         (*len) += ret;
2517         free(newstr);
2518         return;
2519
2520  error:
2521         *len = -1;
2522         *string = NULL;
2523 }
2524
2525 /*
2526    Returns the substring from src between the first occurrence of
2527    the char "front" and the first occurence of the char "back".
2528    Mallocs the return string which must be freed.  Not for use
2529    with wide character strings.
2530 */
2531 char *sstring_sub(const char *src, char front, char back)
2532 {
2533         char *temp1, *temp2, *temp3;
2534         ptrdiff_t len;
2535
2536         temp1 = strchr(src, front);
2537         if (temp1 == NULL) return NULL;
2538         temp2 = strchr(src, back);
2539         if (temp2 == NULL) return NULL;
2540         len = temp2 - temp1;
2541         if (len <= 0) return NULL;
2542         temp3 = (char*)SMB_MALLOC(len);
2543         if (temp3 == NULL) {
2544                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2545                 return NULL;
2546         }
2547         memcpy(temp3, temp1+1, len-1);
2548         temp3[len-1] = '\0';
2549         return temp3;
2550 }
2551
2552 /********************************************************************
2553  Check a string for any occurrences of a specified list of invalid
2554  characters.
2555 ********************************************************************/
2556
2557 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2558 {
2559         int i;
2560
2561         for ( i=0; i<max_len && name[i]; i++ ) {
2562                 /* fail if strchr_m() finds one of the invalid characters */
2563                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2564                         return False;
2565                 }
2566         }
2567
2568         return True;
2569 }
2570
2571
2572 /**
2573 return the number of bytes occupied by a buffer in ASCII format
2574 the result includes the null termination
2575 limited by 'n' bytes
2576 **/
2577 size_t ascii_len_n(const char *src, size_t n)
2578 {
2579         size_t len;
2580
2581         len = strnlen(src, n);
2582         if (len+1 <= n) {
2583                 len += 1;
2584         }
2585
2586         return len;
2587 }
2588
2589 /**
2590 return the number of bytes occupied by a buffer in CH_UTF16 format
2591 the result includes the null termination
2592 **/
2593 size_t utf16_len(const void *buf)
2594 {
2595         size_t len;
2596
2597         for (len = 0; SVAL(buf,len); len += 2) ;
2598
2599         return len + 2;
2600 }
2601
2602 /**
2603 return the number of bytes occupied by a buffer in CH_UTF16 format
2604 the result includes the null termination
2605 limited by 'n' bytes
2606 **/
2607 size_t utf16_len_n(const void *src, size_t n)
2608 {
2609         size_t len;
2610
2611         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2612
2613         if (len+2 <= n) {
2614                 len += 2;
2615         }
2616
2617         return len;
2618 }
2619
2620 /*******************************************************************
2621  Add a shell escape character '\' to any character not in a known list
2622  of characters. UNIX charset format.
2623 *******************************************************************/
2624
2625 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabdefghijklmnopqrstuvwxyz_/ \t.,"
2626 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2627
2628 char *escape_shell_string(const char *src)
2629 {
2630         size_t srclen = strlen(src);
2631         char *ret = SMB_MALLOC((srclen * 2) + 1);
2632         char *dest = ret;
2633         BOOL in_s_quote = False;
2634         BOOL in_d_quote = False;
2635         BOOL next_escaped = False;
2636
2637         if (!ret) {
2638                 return NULL;
2639         }
2640
2641         while (*src) {
2642                 size_t c_size;
2643                 codepoint_t c = next_codepoint(src, &c_size);
2644
2645                 if (c == INVALID_CODEPOINT) {
2646                         SAFE_FREE(ret);
2647                         return NULL;
2648                 }
2649
2650                 if (c_size > 1) {
2651                         memcpy(dest, src, c_size);
2652                         src += c_size;
2653                         dest += c_size;
2654                         next_escaped = False;
2655                         continue;
2656                 }
2657
2658                 /*
2659                  * Deal with backslash escaped state.
2660                  * This only lasts for one character.
2661                  */
2662
2663                 if (next_escaped) {
2664                         *dest++ = *src++;
2665                         next_escaped = False;
2666                         continue;
2667                 }
2668
2669                 /*
2670                  * Deal with single quote state. The
2671                  * only thing we care about is exiting
2672                  * this state.
2673                  */
2674
2675                 if (in_s_quote) {
2676                         if (*src == '\'') {
2677                                 in_s_quote = False;
2678                         }
2679                         *dest++ = *src++;
2680                         continue;
2681                 }
2682
2683                 /* 
2684                  * Deal with double quote state. The most
2685                  * complex state. We must cope with \, meaning
2686                  * possibly escape next char (depending what it
2687                  * is), ", meaning exit this state, and possibly
2688                  * add an \ escape to any unprotected character
2689                  * (listed in INSIDE_DQUOTE_LIST).
2690                  */
2691
2692                 if (in_d_quote) {
2693                         if (*src == '\\') {
2694                                 /* 
2695                                  * Next character might be escaped.
2696                                  * We have to peek. Inside double
2697                                  * quotes only INSIDE_DQUOTE_LIST
2698                                  * characters are escaped by a \.
2699                                  */
2700
2701                                 char nextchar;
2702
2703                                 c = next_codepoint(&src[1], &c_size);
2704                                 if (c == INVALID_CODEPOINT) {
2705                                         SAFE_FREE(ret);
2706                                         return NULL;
2707                                 }
2708                                 if (c_size > 1) {
2709                                         /*
2710                                          * Don't escape the next char.
2711                                          * Just copy the \.
2712                                          */
2713                                         *dest++ = *src++;
2714                                         continue;
2715                                 }
2716
2717                                 nextchar = src[1];
2718
2719                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
2720                                         next_escaped = True;
2721                                 }
2722                                 *dest++ = *src++;
2723                                 continue;
2724                         }
2725
2726                         if (*src == '\"') {
2727                                 /* Exit double quote state. */
2728                                 in_d_quote = False;
2729                                 *dest++ = *src++;
2730                                 continue;
2731                         }
2732
2733                         /*
2734                          * We know the character isn't \ or ",
2735                          * so escape it if it's any of the other
2736                          * possible unprotected characters.
2737                          */
2738
2739                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2740                                 *dest++ = '\\';
2741                         }
2742                         *dest++ = *src++;
2743                         continue;
2744                 }
2745
2746                 /* 
2747                  * From here to the end of the loop we're
2748                  * not in the single or double quote state.
2749                  */
2750
2751                 if (*src == '\\') {
2752                         /* Next character must be escaped. */
2753                         next_escaped = True;
2754                         *dest++ = *src++;
2755                         continue;
2756                 }
2757
2758                 if (*src == '\'') {
2759                         /* Go into single quote state. */
2760                         in_s_quote = True;
2761                         *dest++ = *src++;
2762                         continue;
2763                 }
2764
2765                 if (*src == '\"') {
2766                         /* Go into double quote state. */
2767                         in_d_quote = True;
2768                         *dest++ = *src++;
2769                         continue;
2770                 }
2771
2772                 /* Check if we need to escape the character. */
2773
2774                 if (!strchr(INCLUDE_LIST, (int)*src)) {
2775                         *dest++ = '\\';
2776                 }
2777                 *dest++ = *src++;
2778         }
2779         *dest++ = '\0';
2780         return ret;
2781 }