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