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