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