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