r6014: rather large change set....
[ira/wip.git] / source3 / lib / util_str.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    
5    Copyright (C) Andrew Tridgell 1992-2001
6    Copyright (C) Simo Sorce      2001-2002
7    Copyright (C) Martin Pool     2003
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 /**
27  * @file
28  * @brief String utilities.
29  **/
30
31 /**
32  * Get the next token from a string, return False if none found.
33  * Handles double-quotes.
34  * 
35  * Based on a routine by GJC@VILLAGE.COM. 
36  * Extensively modified by Andrew.Tridgell@anu.edu.au
37  **/
38 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
39 {
40         char *s;
41         char *pbuf;
42         BOOL quoted;
43         size_t len=1;
44
45         if (!ptr)
46                 return(False);
47
48         s = (char *)*ptr;
49
50         /* default to simple separators */
51         if (!sep)
52                 sep = " \t\n\r";
53
54         /* find the first non sep char */
55         while (*s && strchr_m(sep,*s))
56                 s++;
57         
58         /* nothing left? */
59         if (! *s)
60                 return(False);
61         
62         /* copy over the token */
63         pbuf = buff;
64         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65                 if ( *s == '\"' ) {
66                         quoted = !quoted;
67                 } else {
68                         len++;
69                         *pbuf++ = *s;
70                 }
71         }
72         
73         *ptr = (*s) ? s+1 : s;  
74         *pbuf = 0;
75         
76         return(True);
77 }
78
79 /**
80 This is like next_token but is not re-entrant and "remembers" the first 
81 parameter so you can pass NULL. This is useful for user interface code
82 but beware the fact that it is not re-entrant!
83 **/
84
85 static const char *last_ptr=NULL;
86
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
88 {
89         BOOL ret;
90         if (!ptr)
91                 ptr = &last_ptr;
92
93         ret = next_token(ptr, buff, sep, bufsize);
94         last_ptr = *ptr;
95         return ret;     
96 }
97
98 static uint16 tmpbuf[sizeof(pstring)];
99
100 void set_first_token(char *ptr)
101 {
102         last_ptr = ptr;
103 }
104
105 /**
106  Convert list of tokens to array; dependent on above routine.
107  Uses last_ptr from above - bit of a hack.
108 **/
109
110 char **toktocliplist(int *ctok, const char *sep)
111 {
112         char *s=(char *)last_ptr;
113         int ictok=0;
114         char **ret, **iret;
115
116         if (!sep)
117                 sep = " \t\n\r";
118
119         while(*s && strchr_m(sep,*s))
120                 s++;
121
122         /* nothing left? */
123         if (!*s)
124                 return(NULL);
125
126         do {
127                 ictok++;
128                 while(*s && (!strchr_m(sep,*s)))
129                         s++;
130                 while(*s && strchr_m(sep,*s))
131                         *s++=0;
132         } while(*s);
133         
134         *ctok=ictok;
135         s=(char *)last_ptr;
136         
137         if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
138                 return NULL;
139         
140         while(ictok--) {    
141                 *iret++=s;
142                 if (ictok > 0) {
143                         while(*s++)
144                                 ;
145                         while(!*s)
146                                 s++;
147                 }
148         }
149
150         ret[*ctok] = NULL;
151         return ret;
152 }
153
154 /**
155  * Case insensitive string compararison.
156  *
157  * iconv does not directly give us a way to compare strings in
158  * arbitrary unix character sets -- all we can is convert and then
159  * compare.  This is expensive.
160  *
161  * As an optimization, we do a first pass that considers only the
162  * prefix of the strings that is entirely 7-bit.  Within this, we
163  * check whether they have the same value.
164  *
165  * Hopefully this will often give the answer without needing to copy.
166  * In particular it should speed comparisons to literal ascii strings
167  * or comparisons of strings that are "obviously" different.
168  *
169  * If we find a non-ascii character we fall back to converting via
170  * iconv.
171  *
172  * This should never be slower than convering the whole thing, and
173  * often faster.
174  *
175  * A different optimization would be to compare for bitwise equality
176  * in the binary encoding.  (It would be possible thought hairy to do
177  * both simultaneously.)  But in that case if they turn out to be
178  * different, we'd need to restart the whole thing.
179  *
180  * Even better is to implement strcasecmp for each encoding and use a
181  * function pointer. 
182  **/
183 int StrCaseCmp(const char *s, const char *t)
184 {
185
186         const char * ps, * pt;
187         size_t size;
188         smb_ucs2_t *buffer_s, *buffer_t;
189         int ret;
190
191         for (ps = s, pt = t; ; ps++, pt++) {
192                 char us, ut;
193
194                 if (!*ps && !*pt)
195                         return 0; /* both ended */
196                 else if (!*ps)
197                         return -1; /* s is a prefix */
198                 else if (!*pt)
199                         return +1; /* t is a prefix */
200                 else if ((*ps & 0x80) || (*pt & 0x80))
201                         /* not ascii anymore, do it the hard way from here on in */
202                         break;
203
204                 us = toupper(*ps);
205                 ut = toupper(*pt);
206                 if (us == ut)
207                         continue;
208                 else if (us < ut)
209                         return -1;
210                 else if (us > ut)
211                         return +1;
212         }
213
214         size = push_ucs2_allocate(&buffer_s, s);
215         if (size == (size_t)-1) {
216                 return strcmp(s, t); 
217                 /* Not quite the right answer, but finding the right one
218                    under this failure case is expensive, and it's pretty close */
219         }
220         
221         size = push_ucs2_allocate(&buffer_t, t);
222         if (size == (size_t)-1) {
223                 SAFE_FREE(buffer_s);
224                 return strcmp(s, t); 
225                 /* Not quite the right answer, but finding the right one
226                    under this failure case is expensive, and it's pretty close */
227         }
228         
229         ret = strcasecmp_w(buffer_s, buffer_t);
230         SAFE_FREE(buffer_s);
231         SAFE_FREE(buffer_t);
232         return ret;
233 }
234
235
236 /**
237  Case insensitive string compararison, length limited.
238 **/
239 int StrnCaseCmp(const char *s, const char *t, size_t n)
240 {
241         pstring buf1, buf2;
242         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
243         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
244         return strncmp(buf1,buf2,n);
245 }
246
247 /**
248  * Compare 2 strings.
249  *
250  * @note The comparison is case-insensitive.
251  **/
252 BOOL strequal(const char *s1, const char *s2)
253 {
254         if (s1 == s2)
255                 return(True);
256         if (!s1 || !s2)
257                 return(False);
258   
259         return(StrCaseCmp(s1,s2)==0);
260 }
261
262 /**
263  * Compare 2 strings up to and including the nth char.
264  *
265  * @note The comparison is case-insensitive.
266  **/
267 BOOL strnequal(const char *s1,const char *s2,size_t n)
268 {
269   if (s1 == s2)
270           return(True);
271   if (!s1 || !s2 || !n)
272           return(False);
273   
274   return(StrnCaseCmp(s1,s2,n)==0);
275 }
276
277 /**
278  Compare 2 strings (case sensitive).
279 **/
280
281 BOOL strcsequal(const char *s1,const char *s2)
282 {
283   if (s1 == s2)
284           return(True);
285   if (!s1 || !s2)
286           return(False);
287   
288   return(strcmp(s1,s2)==0);
289 }
290
291 /**
292 Do a case-insensitive, whitespace-ignoring string compare.
293 **/
294
295 int strwicmp(const char *psz1, const char *psz2)
296 {
297         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
298         /* appropriate value. */
299         if (psz1 == psz2)
300                 return (0);
301         else if (psz1 == NULL)
302                 return (-1);
303         else if (psz2 == NULL)
304                 return (1);
305
306         /* sync the strings on first non-whitespace */
307         while (1) {
308                 while (isspace((int)*psz1))
309                         psz1++;
310                 while (isspace((int)*psz2))
311                         psz2++;
312                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
313                     || *psz2 == '\0')
314                         break;
315                 psz1++;
316                 psz2++;
317         }
318         return (*psz1 - *psz2);
319 }
320
321
322 /**
323  Convert a string to upper case, but don't modify it.
324 **/
325
326 char *strupper_static(const char *s)
327 {
328         static pstring str;
329
330         pstrcpy(str, s);
331         strupper_m(str);
332
333         return str;
334 }
335
336 /**
337  Convert a string to "normal" form.
338 **/
339
340 void strnorm(char *s, int case_default)
341 {
342         if (case_default == CASE_UPPER)
343                 strupper_m(s);
344         else
345                 strlower_m(s);
346 }
347
348 /**
349  Check if a string is in "normal" case.
350 **/
351
352 BOOL strisnormal(const char *s, int case_default)
353 {
354         if (case_default == CASE_UPPER)
355                 return(!strhaslower(s));
356         
357         return(!strhasupper(s));
358 }
359
360
361 /**
362  String replace.
363  NOTE: oldc and newc must be 7 bit characters
364 **/
365
366 void string_replace( pstring s, char oldc, char newc )
367 {
368         char *p;
369
370         /* this is quite a common operation, so we want it to be
371            fast. We optimise for the ascii case, knowing that all our
372            supported multi-byte character sets are ascii-compatible
373            (ie. they match for the first 128 chars) */
374
375         for (p = s; *p; p++) {
376                 if (*p & 0x80) /* mb string - slow path. */
377                         break;
378                 if (*p == oldc)
379                         *p = newc;
380         }
381
382         if (!*p)
383                 return;
384
385         /* Slow (mb) path. */
386 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
387         /* With compose characters we must restart from the beginning. JRA. */
388         p = s;
389 #endif
390         push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
391         string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
392         pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
393 }
394
395 /**
396  Skip past some strings in a buffer.
397 **/
398
399 char *skip_string(char *buf,size_t n)
400 {
401         while (n--)
402                 buf += strlen(buf) + 1;
403         return(buf);
404 }
405
406 /**
407  Count the number of characters in a string. Normally this will
408  be the same as the number of bytes in a string for single byte strings,
409  but will be different for multibyte.
410 **/
411
412 size_t str_charnum(const char *s)
413 {
414         uint16 tmpbuf2[sizeof(pstring)];
415         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
416         return strlen_w(tmpbuf2);
417 }
418
419 /**
420  Count the number of characters in a string. Normally this will
421  be the same as the number of bytes in a string for single byte strings,
422  but will be different for multibyte.
423 **/
424
425 size_t str_ascii_charnum(const char *s)
426 {
427         pstring tmpbuf2;
428         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
429         return strlen(tmpbuf2);
430 }
431
432 BOOL trim_char(char *s,char cfront,char cback)
433 {
434         BOOL ret = False;
435         char *ep;
436         char *fp = s;
437
438         /* Ignore null or empty strings. */
439         if (!s || (s[0] == '\0'))
440                 return False;
441
442         if (cfront) {
443                 while (*fp && *fp == cfront)
444                         fp++;
445                 if (!*fp) {
446                         /* We ate the string. */
447                         s[0] = '\0';
448                         return True;
449                 }
450                 if (fp != s)
451                         ret = True;
452         }
453
454         ep = fp + strlen(fp) - 1;
455         if (cback) {
456                 /* Attempt ascii only. Bail for mb strings. */
457                 while ((ep >= fp) && (*ep == cback)) {
458                         ret = True;
459                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
460                                 /* Could be mb... bail back to tim_string. */
461                                 char fs[2], bs[2];
462                                 if (cfront) {
463                                         fs[0] = cfront;
464                                         fs[1] = '\0';
465                                 }
466                                 bs[0] = cback;
467                                 bs[1] = '\0';
468                                 return trim_string(s, cfront ? fs : NULL, bs);
469                         } else {
470                                 ep--;
471                         }
472                 }
473                 if (ep < fp) {
474                         /* We ate the string. */
475                         s[0] = '\0';
476                         return True;
477                 }
478         }
479
480         ep[1] = '\0';
481         memmove(s, fp, ep-fp+2);
482         return ret;
483 }
484
485 /**
486  Trim the specified elements off the front and back of a string.
487 **/
488
489 BOOL trim_string(char *s,const char *front,const char *back)
490 {
491         BOOL ret = False;
492         size_t front_len;
493         size_t back_len;
494         size_t len;
495
496         /* Ignore null or empty strings. */
497         if (!s || (s[0] == '\0'))
498                 return False;
499
500         front_len       = front? strlen(front) : 0;
501         back_len        = back? strlen(back) : 0;
502
503         len = strlen(s);
504
505         if (front_len) {
506                 while (len && strncmp(s, front, front_len)==0) {
507                         /* Must use memmove here as src & dest can
508                          * easily overlap. Found by valgrind. JRA. */
509                         memmove(s, s+front_len, (len-front_len)+1);
510                         len -= front_len;
511                         ret=True;
512                 }
513         }
514         
515         if (back_len) {
516                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
517                         s[len-back_len]='\0';
518                         len -= back_len;
519                         ret=True;
520                 }
521         }
522         return ret;
523 }
524
525 /**
526  Does a string have any uppercase chars in it?
527 **/
528
529 BOOL strhasupper(const char *s)
530 {
531         smb_ucs2_t *ptr;
532         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
533         for(ptr=tmpbuf;*ptr;ptr++)
534                 if(isupper_w(*ptr))
535                         return True;
536         return(False);
537 }
538
539 /**
540  Does a string have any lowercase chars in it?
541 **/
542
543 BOOL strhaslower(const char *s)
544 {
545         smb_ucs2_t *ptr;
546         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
547         for(ptr=tmpbuf;*ptr;ptr++)
548                 if(islower_w(*ptr))
549                         return True;
550         return(False);
551 }
552
553 /**
554  Find the number of 'c' chars in a string
555 **/
556
557 size_t count_chars(const char *s,char c)
558 {
559         smb_ucs2_t *ptr;
560         int count;
561         smb_ucs2_t *alloc_tmpbuf = NULL;
562
563         if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
564                 return 0;
565         }
566
567         for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
568                 if(*ptr==UCS2_CHAR(c))
569                         count++;
570
571         SAFE_FREE(alloc_tmpbuf);
572         return(count);
573 }
574
575 /**
576  Safe string copy into a known length string. maxlength does not
577  include the terminating zero.
578 **/
579
580 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
581 {
582         size_t len;
583
584         if (!dest) {
585                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
586                 return NULL;
587         }
588
589 #ifdef DEVELOPER
590         clobber_region(fn,line,dest, maxlength+1);
591 #endif
592
593         if (!src) {
594                 *dest = 0;
595                 return dest;
596         }  
597
598         len = strnlen(src, maxlength+1);
599
600         if (len > maxlength) {
601                 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
602                          (unsigned long)(len-maxlength), (unsigned long)len, 
603                          (unsigned long)maxlength, src));
604                 len = maxlength;
605         }
606       
607         memmove(dest, src, len);
608         dest[len] = 0;
609         return dest;
610 }  
611
612 /**
613  Safe string cat into a string. maxlength does not
614  include the terminating zero.
615 **/
616 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
617 {
618         size_t src_len, dest_len;
619
620         if (!dest) {
621                 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
622                 return NULL;
623         }
624
625         if (!src)
626                 return dest;
627         
628         src_len = strnlen(src, maxlength + 1);
629         dest_len = strnlen(dest, maxlength + 1);
630
631 #ifdef DEVELOPER
632         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
633 #endif
634
635         if (src_len + dest_len > maxlength) {
636                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
637                          (int)(src_len + dest_len - maxlength), src));
638                 if (maxlength > dest_len) {
639                         memcpy(&dest[dest_len], src, maxlength - dest_len);
640                 }
641                 dest[maxlength] = 0;
642                 return NULL;
643         }
644
645         memcpy(&dest[dest_len], src, src_len);
646         dest[dest_len + src_len] = 0;
647         return dest;
648 }
649
650 /**
651  Paranoid strcpy into a buffer of given length (includes terminating
652  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
653  and replaces with '_'. Deliberately does *NOT* check for multibyte
654  characters. Don't change it !
655 **/
656 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
657 {
658         size_t len, i;
659
660 #ifdef DEVELOPER
661         clobber_region(fn, line, dest, maxlength);
662 #endif
663
664         if (!dest) {
665                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
666                 return NULL;
667         }
668
669         if (!src) {
670                 *dest = 0;
671                 return dest;
672         }  
673
674         len = strlen(src);
675         if (len >= maxlength)
676                 len = maxlength - 1;
677
678         if (!other_safe_chars)
679                 other_safe_chars = "";
680
681         for(i = 0; i < len; i++) {
682                 int val = (src[i] & 0xff);
683                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
684                         dest[i] = src[i];
685                 else
686                         dest[i] = '_';
687         }
688
689         dest[i] = '\0';
690
691         return dest;
692 }
693
694 /**
695  Like strncpy but always null terminates. Make sure there is room!
696  The variable n should always be one less than the available size.
697 **/
698 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
699 {
700         char *d = dest;
701
702 #ifdef DEVELOPER
703         clobber_region(fn, line, dest, n+1);
704 #endif
705
706         if (!dest) {
707                 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
708                 return(NULL);
709         }
710
711         if (!src) {
712                 *dest = 0;
713                 return(dest);
714         }
715         
716         while (n-- && (*d = *src)) {
717                 d++;
718                 src++;
719         }
720
721         *d = 0;
722         return(dest);
723 }
724
725 #if 0
726 /**
727  Like strncpy but copies up to the character marker.  always null terminates.
728  returns a pointer to the character marker in the source string (src).
729 **/
730
731 static char *strncpyn(char *dest, const char *src, size_t n, char c)
732 {
733         char *p;
734         size_t str_len;
735
736 #ifdef DEVELOPER
737         clobber_region(dest, n+1);
738 #endif
739         p = strchr_m(src, c);
740         if (p == NULL) {
741                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
742                 return NULL;
743         }
744
745         str_len = PTR_DIFF(p, src);
746         strncpy(dest, src, MIN(n, str_len));
747         dest[str_len] = '\0';
748
749         return p;
750 }
751 #endif
752
753 /**
754  Routine to get hex characters and turn them into a 16 byte array.
755  the array can be variable length, and any non-hex-numeric
756  characters are skipped.  "0xnn" or "0Xnn" is specially catered
757  for.
758
759  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
760
761 **/
762
763 size_t strhex_to_str(char *p, size_t len, const char *strhex)
764 {
765         size_t i;
766         size_t num_chars = 0;
767         unsigned char   lonybble, hinybble;
768         const char     *hexchars = "0123456789ABCDEF";
769         char           *p1 = NULL, *p2 = NULL;
770
771         for (i = 0; i < len && strhex[i] != 0; i++) {
772                 if (strnequal(hexchars, "0x", 2)) {
773                         i++; /* skip two chars */
774                         continue;
775                 }
776
777                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
778                         break;
779
780                 i++; /* next hex digit */
781
782                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
783                         break;
784
785                 /* get the two nybbles */
786                 hinybble = PTR_DIFF(p1, hexchars);
787                 lonybble = PTR_DIFF(p2, hexchars);
788
789                 p[num_chars] = (hinybble << 4) | lonybble;
790                 num_chars++;
791
792                 p1 = NULL;
793                 p2 = NULL;
794         }
795         return num_chars;
796 }
797
798 DATA_BLOB strhex_to_data_blob(const char *strhex) 
799 {
800         DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
801
802         ret_blob.length = strhex_to_str((char*)ret_blob.data,   
803                                         strlen(strhex), 
804                                         strhex);
805
806         return ret_blob;
807 }
808
809 /**
810  * Routine to print a buffer as HEX digits, into an allocated string.
811  */
812
813 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
814 {
815         int i;
816         char *hex_buffer;
817
818         *out_hex_buffer = SMB_XMALLOC_ARRAY(char, (len*2)+1);
819         hex_buffer = *out_hex_buffer;
820
821         for (i = 0; i < len; i++)
822                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
823 }
824
825 /**
826  Check if a string is part of a list.
827 **/
828
829 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
830 {
831         pstring tok;
832         const char *p=list;
833
834         if (!list)
835                 return(False);
836
837         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
838                 if (casesensitive) {
839                         if (strcmp(tok,s) == 0)
840                                 return(True);
841                 } else {
842                         if (StrCaseCmp(tok,s) == 0)
843                                 return(True);
844                 }
845         }
846         return(False);
847 }
848
849 /* this is used to prevent lots of mallocs of size 1 */
850 static char *null_string = NULL;
851
852 /**
853  Set a string value, allocing the space for the string
854 **/
855
856 static BOOL string_init(char **dest,const char *src)
857 {
858         size_t l;
859         if (!src)     
860                 src = "";
861
862         l = strlen(src);
863
864         if (l == 0) {
865                 if (!null_string) {
866                         if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
867                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
868                                 return False;
869                         }
870                         *null_string = 0;
871                 }
872                 *dest = null_string;
873         } else {
874                 (*dest) = SMB_STRDUP(src);
875                 if ((*dest) == NULL) {
876                         DEBUG(0,("Out of memory in string_init\n"));
877                         return False;
878                 }
879         }
880         return(True);
881 }
882
883 /**
884  Free a string value.
885 **/
886
887 void string_free(char **s)
888 {
889         if (!s || !(*s))
890                 return;
891         if (*s == null_string)
892                 *s = NULL;
893         SAFE_FREE(*s);
894 }
895
896 /**
897  Set a string value, deallocating any existing space, and allocing the space
898  for the string
899 **/
900
901 BOOL string_set(char **dest,const char *src)
902 {
903         string_free(dest);
904         return(string_init(dest,src));
905 }
906
907 /**
908  Substitute a string for a pattern in another string. Make sure there is 
909  enough room!
910
911  This routine looks for pattern in s and replaces it with 
912  insert. It may do multiple replacements.
913
914  Any of " ; ' $ or ` in the insert string are replaced with _
915  if len==0 then the string cannot be extended. This is different from the old
916  use of len==0 which was for no length checks to be done.
917 **/
918
919 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
920 {
921         char *p;
922         ssize_t ls,lp,li, i;
923
924         if (!insert || !pattern || !*pattern || !s)
925                 return;
926
927         ls = (ssize_t)strlen(s);
928         lp = (ssize_t)strlen(pattern);
929         li = (ssize_t)strlen(insert);
930
931         if (len == 0)
932                 len = ls + 1; /* len is number of *bytes* */
933
934         while (lp <= ls && (p = strstr_m(s,pattern))) {
935                 if (ls + (li-lp) >= len) {
936                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
937                                  (int)(ls + (li-lp) - len),
938                                  pattern, (int)len));
939                         break;
940                 }
941                 if (li != lp) {
942                         memmove(p+li,p+lp,strlen(p+lp)+1);
943                 }
944                 for (i=0;i<li;i++) {
945                         switch (insert[i]) {
946                         case '`':
947                         case '"':
948                         case '\'':
949                         case ';':
950                         case '$':
951                         case '%':
952                         case '\r':
953                         case '\n':
954                                 p[i] = '_';
955                                 break;
956                         default:
957                                 p[i] = insert[i];
958                         }
959                 }
960                 s = p + li;
961                 ls += (li-lp);
962         }
963 }
964
965 void fstring_sub(char *s,const char *pattern,const char *insert)
966 {
967         string_sub(s, pattern, insert, sizeof(fstring));
968 }
969
970 void pstring_sub(char *s,const char *pattern,const char *insert)
971 {
972         string_sub(s, pattern, insert, sizeof(pstring));
973 }
974
975 /**
976  Similar to string_sub, but it will accept only allocated strings
977  and may realloc them so pay attention at what you pass on no
978  pointers inside strings, no pstrings or const may be passed
979  as string.
980 **/
981
982 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
983 {
984         char *p, *in;
985         char *s;
986         ssize_t ls,lp,li,ld, i;
987
988         if (!insert || !pattern || !*pattern || !string || !*string)
989                 return NULL;
990
991         s = string;
992
993         in = SMB_STRDUP(insert);
994         if (!in) {
995                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
996                 return NULL;
997         }
998         ls = (ssize_t)strlen(s);
999         lp = (ssize_t)strlen(pattern);
1000         li = (ssize_t)strlen(insert);
1001         ld = li - lp;
1002         for (i=0;i<li;i++) {
1003                 switch (in[i]) {
1004                         case '`':
1005                         case '"':
1006                         case '\'':
1007                         case ';':
1008                         case '$':
1009                         case '%':
1010                         case '\r':
1011                         case '\n':
1012                                 in[i] = '_';
1013                         default:
1014                                 /* ok */
1015                                 break;
1016                 }
1017         }
1018         
1019         while ((p = strstr_m(s,pattern))) {
1020                 if (ld > 0) {
1021                         int offset = PTR_DIFF(s,string);
1022                         char *t = SMB_REALLOC(string, ls + ld + 1);
1023                         if (!t) {
1024                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1025                                 SAFE_FREE(in);
1026                                 return NULL;
1027                         }
1028                         string = t;
1029                         p = t + offset + (p - s);
1030                 }
1031                 if (li != lp) {
1032                         memmove(p+li,p+lp,strlen(p+lp)+1);
1033                 }
1034                 memcpy(p, in, li);
1035                 s = p + li;
1036                 ls += ld;
1037         }
1038         SAFE_FREE(in);
1039         return string;
1040 }
1041
1042 /**
1043  Similar to string_sub() but allows for any character to be substituted. 
1044  Use with caution!
1045  if len==0 then the string cannot be extended. This is different from the old
1046  use of len==0 which was for no length checks to be done.
1047 **/
1048
1049 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1050 {
1051         char *p;
1052         ssize_t ls,lp,li;
1053
1054         if (!insert || !pattern || !s)
1055                 return;
1056
1057         ls = (ssize_t)strlen(s);
1058         lp = (ssize_t)strlen(pattern);
1059         li = (ssize_t)strlen(insert);
1060
1061         if (!*pattern)
1062                 return;
1063         
1064         if (len == 0)
1065                 len = ls + 1; /* len is number of *bytes* */
1066         
1067         while (lp <= ls && (p = strstr_m(s,pattern))) {
1068                 if (ls + (li-lp) >= len) {
1069                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1070                                  (int)(ls + (li-lp) - len),
1071                                  pattern, (int)len));
1072                         break;
1073                 }
1074                 if (li != lp) {
1075                         memmove(p+li,p+lp,strlen(p+lp)+1);
1076                 }
1077                 memcpy(p, insert, li);
1078                 s = p + li;
1079                 ls += (li-lp);
1080         }
1081 }
1082
1083 /**
1084  Similar to all_string_sub but for unicode strings.
1085  Return a new allocated unicode string.
1086  similar to string_sub() but allows for any character to be substituted.
1087  Use with caution!
1088 **/
1089
1090 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1091                                 const smb_ucs2_t *insert)
1092 {
1093         smb_ucs2_t *r, *rp;
1094         const smb_ucs2_t *sp;
1095         size_t  lr, lp, li, lt;
1096
1097         if (!insert || !pattern || !*pattern || !s)
1098                 return NULL;
1099
1100         lt = (size_t)strlen_w(s);
1101         lp = (size_t)strlen_w(pattern);
1102         li = (size_t)strlen_w(insert);
1103
1104         if (li > lp) {
1105                 const smb_ucs2_t *st = s;
1106                 int ld = li - lp;
1107                 while ((sp = strstr_w(st, pattern))) {
1108                         st = sp + lp;
1109                         lt += ld;
1110                 }
1111         }
1112
1113         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1114         if (!r) {
1115                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1116                 return NULL;
1117         }
1118
1119         while ((sp = strstr_w(s, pattern))) {
1120                 memcpy(rp, s, (sp - s));
1121                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1122                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1123                 s = sp + lp;
1124                 rp += li;
1125         }
1126         lr = ((rp - r) / sizeof(smb_ucs2_t));
1127         if (lr < lt) {
1128                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1129                 rp += (lt - lr);
1130         }
1131         *rp = 0;
1132
1133         return r;
1134 }
1135
1136 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1137                                              const char *insert)
1138 {
1139         wpstring p, i;
1140
1141         if (!insert || !pattern || !s)
1142                 return NULL;
1143         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1144         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1145         return all_string_sub_w(s, p, i);
1146 }
1147
1148 #if 0
1149 /**
1150  Splits out the front and back at a separator.
1151 **/
1152
1153 static void split_at_last_component(char *path, char *front, char sep, char *back)
1154 {
1155         char *p = strrchr_m(path, sep);
1156
1157         if (p != NULL)
1158                 *p = 0;
1159
1160         if (front != NULL)
1161                 pstrcpy(front, path);
1162
1163         if (p != NULL) {
1164                 if (back != NULL)
1165                         pstrcpy(back, p+1);
1166                 *p = '\\';
1167         } else {
1168                 if (back != NULL)
1169                         back[0] = 0;
1170         }
1171 }
1172 #endif
1173
1174 /**
1175  Write an octal as a string.
1176 **/
1177
1178 const char *octal_string(int i)
1179 {
1180         static char ret[64];
1181         if (i == -1)
1182                 return "-1";
1183         slprintf(ret, sizeof(ret)-1, "0%o", i);
1184         return ret;
1185 }
1186
1187
1188 /**
1189  Truncate a string at a specified length.
1190 **/
1191
1192 char *string_truncate(char *s, unsigned int length)
1193 {
1194         if (s && strlen(s) > length)
1195                 s[length] = 0;
1196         return s;
1197 }
1198
1199 /**
1200  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1201  We convert via ucs2 for now.
1202 **/
1203
1204 char *strchr_m(const char *src, char c)
1205 {
1206         wpstring ws;
1207         pstring s2;
1208         smb_ucs2_t *p;
1209         const char *s;
1210
1211         /* characters below 0x3F are guaranteed to not appear in
1212            non-initial position in multi-byte charsets */
1213         if ((c & 0xC0) == 0) {
1214                 return strchr(src, c);
1215         }
1216
1217         /* this is quite a common operation, so we want it to be
1218            fast. We optimise for the ascii case, knowing that all our
1219            supported multi-byte character sets are ascii-compatible
1220            (ie. they match for the first 128 chars) */
1221
1222         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1223                 if (*s == c)
1224                         return (char *)s;
1225         }
1226
1227         if (!*s)
1228                 return NULL;
1229
1230 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1231         /* With compose characters we must restart from the beginning. JRA. */
1232         s = src;
1233 #endif
1234
1235         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1236         p = strchr_w(ws, UCS2_CHAR(c));
1237         if (!p)
1238                 return NULL;
1239         *p = 0;
1240         pull_ucs2_pstring(s2, ws);
1241         return (char *)(s+strlen(s2));
1242 }
1243
1244 char *strrchr_m(const char *s, char c)
1245 {
1246         /* characters below 0x3F are guaranteed to not appear in
1247            non-initial position in multi-byte charsets */
1248         if ((c & 0xC0) == 0) {
1249                 return strrchr(s, c);
1250         }
1251
1252         /* this is quite a common operation, so we want it to be
1253            fast. We optimise for the ascii case, knowing that all our
1254            supported multi-byte character sets are ascii-compatible
1255            (ie. they match for the first 128 chars). Also, in Samba
1256            we only search for ascii characters in 'c' and that
1257            in all mb character sets with a compound character
1258            containing c, if 'c' is not a match at position
1259            p, then p[-1] > 0x7f. JRA. */
1260
1261         {
1262                 size_t len = strlen(s);
1263                 const char *cp = s;
1264                 BOOL got_mb = False;
1265
1266                 if (len == 0)
1267                         return NULL;
1268                 cp += (len - 1);
1269                 do {
1270                         if (c == *cp) {
1271                                 /* Could be a match. Part of a multibyte ? */
1272                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1273                                         /* Yep - go slow :-( */
1274                                         got_mb = True;
1275                                         break;
1276                                 }
1277                                 /* No - we have a match ! */
1278                                 return (char *)cp;
1279                         }
1280                 } while (cp-- != s);
1281                 if (!got_mb)
1282                         return NULL;
1283         }
1284
1285         /* String contained a non-ascii char. Slow path. */
1286         {
1287                 wpstring ws;
1288                 pstring s2;
1289                 smb_ucs2_t *p;
1290
1291                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1292                 p = strrchr_w(ws, UCS2_CHAR(c));
1293                 if (!p)
1294                         return NULL;
1295                 *p = 0;
1296                 pull_ucs2_pstring(s2, ws);
1297                 return (char *)(s+strlen(s2));
1298         }
1299 }
1300
1301 /***********************************************************************
1302  Return the equivalent of doing strrchr 'n' times - always going
1303  backwards.
1304 ***********************************************************************/
1305
1306 char *strnrchr_m(const char *s, char c, unsigned int n)
1307 {
1308         wpstring ws;
1309         pstring s2;
1310         smb_ucs2_t *p;
1311
1312         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1313         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1314         if (!p)
1315                 return NULL;
1316         *p = 0;
1317         pull_ucs2_pstring(s2, ws);
1318         return (char *)(s+strlen(s2));
1319 }
1320
1321 /***********************************************************************
1322  strstr_m - We convert via ucs2 for now.
1323 ***********************************************************************/
1324
1325 char *strstr_m(const char *src, const char *findstr)
1326 {
1327         smb_ucs2_t *p;
1328         smb_ucs2_t *src_w, *find_w;
1329         const char *s;
1330         char *s2;
1331         char *retp;
1332
1333         size_t findstr_len = 0;
1334
1335         /* for correctness */
1336         if (!findstr[0]) {
1337                 return (char*)src;
1338         }
1339
1340         /* Samba does single character findstr calls a *lot*. */
1341         if (findstr[1] == '\0')
1342                 return strchr_m(src, *findstr);
1343
1344         /* We optimise for the ascii case, knowing that all our
1345            supported multi-byte character sets are ascii-compatible
1346            (ie. they match for the first 128 chars) */
1347
1348         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1349                 if (*s == *findstr) {
1350                         if (!findstr_len) 
1351                                 findstr_len = strlen(findstr);
1352
1353                         if (strncmp(s, findstr, findstr_len) == 0) {
1354                                 return (char *)s;
1355                         }
1356                 }
1357         }
1358
1359         if (!*s)
1360                 return NULL;
1361
1362 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1363         /* 'make check' fails unless we do this */
1364
1365         /* With compose characters we must restart from the beginning. JRA. */
1366         s = src;
1367 #endif
1368
1369         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1370                 DEBUG(0,("strstr_m: src malloc fail\n"));
1371                 return NULL;
1372         }
1373         
1374         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1375                 SAFE_FREE(src_w);
1376                 DEBUG(0,("strstr_m: find malloc fail\n"));
1377                 return NULL;
1378         }
1379
1380         p = strstr_w(src_w, find_w);
1381
1382         if (!p) {
1383                 SAFE_FREE(src_w);
1384                 SAFE_FREE(find_w);
1385                 return NULL;
1386         }
1387         
1388         *p = 0;
1389         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1390                 SAFE_FREE(src_w);
1391                 SAFE_FREE(find_w);
1392                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1393                 return NULL;
1394         }
1395         retp = (char *)(s+strlen(s2));
1396         SAFE_FREE(src_w);
1397         SAFE_FREE(find_w);
1398         SAFE_FREE(s2);
1399         return retp;
1400 }
1401
1402 /**
1403  Convert a string to lower case.
1404 **/
1405
1406 void strlower_m(char *s)
1407 {
1408         size_t len;
1409         int errno_save;
1410
1411         /* this is quite a common operation, so we want it to be
1412            fast. We optimise for the ascii case, knowing that all our
1413            supported multi-byte character sets are ascii-compatible
1414            (ie. they match for the first 128 chars) */
1415
1416         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1417                 *s = tolower((unsigned char)*s);
1418                 s++;
1419         }
1420
1421         if (!*s)
1422                 return;
1423
1424         /* I assume that lowercased string takes the same number of bytes
1425          * as source string even in UTF-8 encoding. (VIV) */
1426         len = strlen(s) + 1;
1427         errno_save = errno;
1428         errno = 0;
1429         unix_strlower(s,len,s,len);     
1430         /* Catch mb conversion errors that may not terminate. */
1431         if (errno)
1432                 s[len-1] = '\0';
1433         errno = errno_save;
1434 }
1435
1436 /**
1437  Convert a string to upper case.
1438 **/
1439
1440 void strupper_m(char *s)
1441 {
1442         size_t len;
1443         int errno_save;
1444
1445         /* this is quite a common operation, so we want it to be
1446            fast. We optimise for the ascii case, knowing that all our
1447            supported multi-byte character sets are ascii-compatible
1448            (ie. they match for the first 128 chars) */
1449
1450         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1451                 *s = toupper((unsigned char)*s);
1452                 s++;
1453         }
1454
1455         if (!*s)
1456                 return;
1457
1458         /* I assume that lowercased string takes the same number of bytes
1459          * as source string even in multibyte encoding. (VIV) */
1460         len = strlen(s) + 1;
1461         errno_save = errno;
1462         errno = 0;
1463         unix_strupper(s,len,s,len);     
1464         /* Catch mb conversion errors that may not terminate. */
1465         if (errno)
1466                 s[len-1] = '\0';
1467         errno = errno_save;
1468 }
1469
1470 /**
1471  Return a RFC2254 binary string representation of a buffer.
1472  Used in LDAP filters.
1473  Caller must free.
1474 **/
1475
1476 char *binary_string(char *buf, int len)
1477 {
1478         char *s;
1479         int i, j;
1480         const char *hex = "0123456789ABCDEF";
1481         s = SMB_MALLOC(len * 3 + 1);
1482         if (!s)
1483                 return NULL;
1484         for (j=i=0;i<len;i++) {
1485                 s[j] = '\\';
1486                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1487                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1488                 j += 3;
1489         }
1490         s[j] = 0;
1491         return s;
1492 }
1493
1494 /**
1495  Just a typesafety wrapper for snprintf into a pstring.
1496 **/
1497
1498  int pstr_sprintf(pstring s, const char *fmt, ...)
1499 {
1500         va_list ap;
1501         int ret;
1502
1503         va_start(ap, fmt);
1504         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1505         va_end(ap);
1506         return ret;
1507 }
1508
1509
1510 /**
1511  Just a typesafety wrapper for snprintf into a fstring.
1512 **/
1513
1514 int fstr_sprintf(fstring s, const char *fmt, ...)
1515 {
1516         va_list ap;
1517         int ret;
1518
1519         va_start(ap, fmt);
1520         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1521         va_end(ap);
1522         return ret;
1523 }
1524
1525
1526 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1527 /**
1528  Some platforms don't have strndup.
1529 **/
1530 #if defined(PARANOID_MALLOC_CHECKER)
1531 #undef strndup
1532 #endif
1533
1534  char *strndup(const char *s, size_t n)
1535 {
1536         char *ret;
1537         
1538         n = strnlen(s, n);
1539         ret = SMB_MALLOC(n+1);
1540         if (!ret)
1541                 return NULL;
1542         memcpy(ret, s, n);
1543         ret[n] = 0;
1544
1545         return ret;
1546 }
1547
1548 #if defined(PARANOID_MALLOC_CHECKER)
1549 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1550 #endif
1551
1552 #endif
1553
1554 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1555 /**
1556  Some platforms don't have strnlen
1557 **/
1558
1559  size_t strnlen(const char *s, size_t n)
1560 {
1561         size_t i;
1562         for (i=0; i<n && s[i] != '\0'; i++)
1563                 /* noop */ ;
1564         return i;
1565 }
1566 #endif
1567
1568 /**
1569  List of Strings manipulation functions
1570 **/
1571
1572 #define S_LIST_ABS 16 /* List Allocation Block Size */
1573
1574 char **str_list_make(const char *string, const char *sep)
1575 {
1576         char **list, **rlist;
1577         const char *str;
1578         char *s;
1579         int num, lsize;
1580         pstring tok;
1581         
1582         if (!string || !*string)
1583                 return NULL;
1584         s = SMB_STRDUP(string);
1585         if (!s) {
1586                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1587                 return NULL;
1588         }
1589         if (!sep) sep = LIST_SEP;
1590         
1591         num = lsize = 0;
1592         list = NULL;
1593         
1594         str = s;
1595         while (next_token(&str, tok, sep, sizeof(tok))) {               
1596                 if (num == lsize) {
1597                         lsize += S_LIST_ABS;
1598                         rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1599                         if (!rlist) {
1600                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1601                                 str_list_free(&list);
1602                                 SAFE_FREE(s);
1603                                 return NULL;
1604                         } else
1605                                 list = rlist;
1606                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1607                 }
1608                 
1609                 list[num] = SMB_STRDUP(tok);
1610                 if (!list[num]) {
1611                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1612                         str_list_free(&list);
1613                         SAFE_FREE(s);
1614                         return NULL;
1615                 }
1616         
1617                 num++;  
1618         }
1619         
1620         SAFE_FREE(s);
1621         return list;
1622 }
1623
1624 BOOL str_list_copy(char ***dest, const char **src)
1625 {
1626         char **list, **rlist;
1627         int num, lsize;
1628         
1629         *dest = NULL;
1630         if (!src)
1631                 return False;
1632         
1633         num = lsize = 0;
1634         list = NULL;
1635                 
1636         while (src[num]) {
1637                 if (num == lsize) {
1638                         lsize += S_LIST_ABS;
1639                         rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1640                         if (!rlist) {
1641                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1642                                 str_list_free(&list);
1643                                 return False;
1644                         } else
1645                                 list = rlist;
1646                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1647                 }
1648                 
1649                 list[num] = SMB_STRDUP(src[num]);
1650                 if (!list[num]) {
1651                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1652                         str_list_free(&list);
1653                         return False;
1654                 }
1655
1656                 num++;
1657         }
1658         
1659         *dest = list;
1660         return True;    
1661 }
1662
1663 /**
1664  * Return true if all the elements of the list match exactly.
1665  **/
1666 BOOL str_list_compare(char **list1, char **list2)
1667 {
1668         int num;
1669         
1670         if (!list1 || !list2)
1671                 return (list1 == list2); 
1672         
1673         for (num = 0; list1[num]; num++) {
1674                 if (!list2[num])
1675                         return False;
1676                 if (!strcsequal(list1[num], list2[num]))
1677                         return False;
1678         }
1679         if (list2[num])
1680                 return False; /* if list2 has more elements than list1 fail */
1681         
1682         return True;
1683 }
1684
1685 void str_list_free(char ***list)
1686 {
1687         char **tlist;
1688         
1689         if (!list || !*list)
1690                 return;
1691         tlist = *list;
1692         for(; *tlist; tlist++)
1693                 SAFE_FREE(*tlist);
1694         SAFE_FREE(*list);
1695 }
1696
1697 /******************************************************************************
1698  *****************************************************************************/
1699
1700 int str_list_count( const char **list )
1701 {
1702         int i = 0;
1703
1704         /* count the number of list members */
1705         
1706         for ( i=0; *list; i++, list++ );
1707         
1708         return i;
1709 }
1710
1711 /******************************************************************************
1712  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1713  for the work
1714  *****************************************************************************/
1715  
1716 BOOL str_list_sub_basic( char **list, const char *smb_name )
1717 {
1718         char *s, *tmpstr;
1719         
1720         while ( *list ) {
1721                 s = *list;
1722                 tmpstr = alloc_sub_basic(smb_name, s);
1723                 if ( !tmpstr ) {
1724                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1725                         return False;
1726                 }
1727
1728                 SAFE_FREE(*list);
1729                 *list = tmpstr;
1730                         
1731                 list++;
1732         }
1733
1734         return True;
1735 }
1736
1737 /******************************************************************************
1738  substritute a specific pattern in a string list
1739  *****************************************************************************/
1740  
1741 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1742 {
1743         char *p, *s, *t;
1744         ssize_t ls, lp, li, ld, i, d;
1745
1746         if (!list)
1747                 return False;
1748         if (!pattern)
1749                 return False;
1750         if (!insert)
1751                 return False;
1752
1753         lp = (ssize_t)strlen(pattern);
1754         li = (ssize_t)strlen(insert);
1755         ld = li -lp;
1756                         
1757         while (*list) {
1758                 s = *list;
1759                 ls = (ssize_t)strlen(s);
1760
1761                 while ((p = strstr_m(s, pattern))) {
1762                         t = *list;
1763                         d = p -t;
1764                         if (ld) {
1765                                 t = (char *) SMB_MALLOC(ls +ld +1);
1766                                 if (!t) {
1767                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1768                                         return False;
1769                                 }
1770                                 memcpy(t, *list, d);
1771                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1772                                 SAFE_FREE(*list);
1773                                 *list = t;
1774                                 ls += ld;
1775                                 s = t +d +li;
1776                         }
1777                         
1778                         for (i = 0; i < li; i++) {
1779                                 switch (insert[i]) {
1780                                         case '`':
1781                                         case '"':
1782                                         case '\'':
1783                                         case ';':
1784                                         case '$':
1785                                         case '%':
1786                                         case '\r':
1787                                         case '\n':
1788                                                 t[d +i] = '_';
1789                                                 break;
1790                                         default:
1791                                                 t[d +i] = insert[i];
1792                                 }
1793                         }       
1794                 }
1795                 
1796                 
1797                 list++;
1798         }
1799         
1800         return True;
1801 }
1802
1803
1804 #define IPSTR_LIST_SEP  ","
1805 #define IPSTR_LIST_CHAR ','
1806
1807 /**
1808  * Add ip string representation to ipstr list. Used also
1809  * as part of @function ipstr_list_make
1810  *
1811  * @param ipstr_list pointer to string containing ip list;
1812  *        MUST BE already allocated and IS reallocated if necessary
1813  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1814  *        as a result of reallocation)
1815  * @param ip IP address which is to be added to list
1816  * @return pointer to string appended with new ip and possibly
1817  *         reallocated to new length
1818  **/
1819
1820 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1821 {
1822         char* new_ipstr = NULL;
1823         
1824         /* arguments checking */
1825         if (!ipstr_list || !service) return NULL;
1826
1827         /* attempt to convert ip to a string and append colon separator to it */
1828         if (*ipstr_list) {
1829                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1830                         inet_ntoa(service->ip), service->port);
1831                 SAFE_FREE(*ipstr_list);
1832         } else {
1833                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1834         }
1835         *ipstr_list = new_ipstr;
1836         return *ipstr_list;
1837 }
1838
1839
1840 /**
1841  * Allocate and initialise an ipstr list using ip adresses
1842  * passed as arguments.
1843  *
1844  * @param ipstr_list pointer to string meant to be allocated and set
1845  * @param ip_list array of ip addresses to place in the list
1846  * @param ip_count number of addresses stored in ip_list
1847  * @return pointer to allocated ip string
1848  **/
1849  
1850 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1851 {
1852         int i;
1853         
1854         /* arguments checking */
1855         if (!ip_list && !ipstr_list) return 0;
1856
1857         *ipstr_list = NULL;
1858         
1859         /* process ip addresses given as arguments */
1860         for (i = 0; i < ip_count; i++)
1861                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1862         
1863         return (*ipstr_list);
1864 }
1865
1866
1867 /**
1868  * Parse given ip string list into array of ip addresses
1869  * (as ip_service structures)  
1870  *    e.g. 192.168.1.100:389,192.168.1.78, ...
1871  *
1872  * @param ipstr ip string list to be parsed 
1873  * @param ip_list pointer to array of ip addresses which is
1874  *        allocated by this function and must be freed by caller
1875  * @return number of succesfully parsed addresses
1876  **/
1877  
1878 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1879 {
1880         fstring token_str;
1881         size_t count;
1882         int i;
1883
1884         if (!ipstr_list || !ip_list) 
1885                 return 0;
1886         
1887         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1888         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1889                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1890                 return 0;
1891         }
1892         
1893         for ( i=0; 
1894                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
1895                 i++ ) 
1896         {
1897                 struct in_addr addr;
1898                 unsigned port = 0;      
1899                 char *p = strchr(token_str, ':');
1900                 
1901                 if (p) {
1902                         *p = 0;
1903                         port = atoi(p+1);
1904                 }
1905
1906                 /* convert single token to ip address */
1907                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1908                         break;
1909                                 
1910                 (*ip_list)[i].ip = addr;
1911                 (*ip_list)[i].port = port;
1912         }
1913         
1914         return count;
1915 }
1916
1917
1918 /**
1919  * Safely free ip string list
1920  *
1921  * @param ipstr_list ip string list to be freed
1922  **/
1923
1924 void ipstr_list_free(char* ipstr_list)
1925 {
1926         SAFE_FREE(ipstr_list);
1927 }
1928
1929
1930 /**
1931  Unescape a URL encoded string, in place.
1932 **/
1933
1934 void rfc1738_unescape(char *buf)
1935 {
1936         char *p=buf;
1937
1938         while (p && *p && (p=strchr_m(p,'%'))) {
1939                 int c1 = p[1];
1940                 int c2 = p[2];
1941
1942                 if (c1 >= '0' && c1 <= '9')
1943                         c1 = c1 - '0';
1944                 else if (c1 >= 'A' && c1 <= 'F')
1945                         c1 = 10 + c1 - 'A';
1946                 else if (c1 >= 'a' && c1 <= 'f')
1947                         c1 = 10 + c1 - 'a';
1948                 else {p++; continue;}
1949
1950                 if (c2 >= '0' && c2 <= '9')
1951                         c2 = c2 - '0';
1952                 else if (c2 >= 'A' && c2 <= 'F')
1953                         c2 = 10 + c2 - 'A';
1954                 else if (c2 >= 'a' && c2 <= 'f')
1955                         c2 = 10 + c2 - 'a';
1956                 else {p++; continue;}
1957                         
1958                 *p = (c1<<4) | c2;
1959
1960                 memmove(p+1, p+3, strlen(p+3)+1);
1961                 p++;
1962         }
1963 }
1964
1965 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1966
1967 /**
1968  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1969  **/
1970 DATA_BLOB base64_decode_data_blob(const char *s)
1971 {
1972         int bit_offset, byte_offset, idx, i, n;
1973         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1974         unsigned char *d = decoded.data;
1975         char *p;
1976
1977         n=i=0;
1978
1979         while (*s && (p=strchr_m(b64,*s))) {
1980                 idx = (int)(p - b64);
1981                 byte_offset = (i*6)/8;
1982                 bit_offset = (i*6)%8;
1983                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1984                 if (bit_offset < 3) {
1985                         d[byte_offset] |= (idx << (2-bit_offset));
1986                         n = byte_offset+1;
1987                 } else {
1988                         d[byte_offset] |= (idx >> (bit_offset-2));
1989                         d[byte_offset+1] = 0;
1990                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1991                         n = byte_offset+2;
1992                 }
1993                 s++; i++;
1994         }
1995
1996         if ((n > 0) && (*s == '=')) {
1997                 n -= 1;
1998         }
1999
2000         /* fix up length */
2001         decoded.length = n;
2002         return decoded;
2003 }
2004
2005 /**
2006  * Decode a base64 string in-place - wrapper for the above
2007  **/
2008 void base64_decode_inplace(char *s)
2009 {
2010         DATA_BLOB decoded = base64_decode_data_blob(s);
2011
2012         if ( decoded.length != 0 ) {
2013                 memcpy(s, decoded.data, decoded.length);
2014
2015                 /* null terminate */
2016                 s[decoded.length] = '\0';
2017         } else {
2018                 *s = '\0';
2019         }
2020
2021         data_blob_free(&decoded);
2022 }
2023
2024 /**
2025  * Encode a base64 string into a malloc()ed string caller to free.
2026  *
2027  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2028  **/
2029 char * base64_encode_data_blob(DATA_BLOB data)
2030 {
2031         int bits = 0;
2032         int char_count = 0;
2033         size_t out_cnt, len, output_len;
2034         char *result;
2035
2036         if (!data.length || !data.data)
2037                 return NULL;
2038
2039         out_cnt = 0;
2040         len = data.length;
2041         output_len = data.length * 2;
2042         result = SMB_MALLOC(output_len); /* get us plenty of space */
2043
2044         while (len-- && out_cnt < (data.length * 2) - 5) {
2045                 int c = (unsigned char) *(data.data++);
2046                 bits += c;
2047                 char_count++;
2048                 if (char_count == 3) {
2049                         result[out_cnt++] = b64[bits >> 18];
2050                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2051                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2052             result[out_cnt++] = b64[bits & 0x3f];
2053             bits = 0;
2054             char_count = 0;
2055         } else {
2056             bits <<= 8;
2057         }
2058     }
2059     if (char_count != 0) {
2060         bits <<= 16 - (8 * char_count);
2061         result[out_cnt++] = b64[bits >> 18];
2062         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2063         if (char_count == 1) {
2064             result[out_cnt++] = '=';
2065             result[out_cnt++] = '=';
2066         } else {
2067             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2068             result[out_cnt++] = '=';
2069         }
2070     }
2071     result[out_cnt] = '\0';     /* terminate */
2072     return result;
2073 }
2074
2075 /* read a SMB_BIG_UINT from a string */
2076 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2077 {
2078
2079         SMB_BIG_UINT val = -1;
2080         const char *p = nptr;
2081         
2082         while (p && *p && isspace(*p))
2083                 p++;
2084 #ifdef LARGE_SMB_OFF_T
2085         sscanf(p,"%llu",&val);  
2086 #else /* LARGE_SMB_OFF_T */
2087         sscanf(p,"%lu",&val);
2088 #endif /* LARGE_SMB_OFF_T */
2089         if (entptr) {
2090                 while (p && *p && isdigit(*p))
2091                         p++;
2092                 *entptr = p;
2093         }
2094
2095         return val;
2096 }
2097
2098 void string_append(char **left, const char *right)
2099 {
2100         int new_len = strlen(right) + 1;
2101
2102         if (*left == NULL) {
2103                 *left = SMB_MALLOC(new_len);
2104                 *left[0] = '\0';
2105         } else {
2106                 new_len += strlen(*left);
2107                 *left = SMB_REALLOC(*left, new_len);
2108         }
2109
2110         if (*left == NULL)
2111                 return;
2112
2113         safe_strcat(*left, right, new_len-1);
2114 }
2115
2116 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2117                          const char *str, const char ***strings,
2118                          int *num)
2119 {
2120         char *dup_str = talloc_strdup(mem_ctx, str);
2121
2122         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2123
2124         if ((*strings == NULL) || (dup_str == NULL))
2125                 return False;
2126
2127         (*strings)[*num] = dup_str;
2128         *num += 1;
2129         return True;
2130 }