r9201: Ouch.... :-(
[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    
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(TALLOC_CTX *mem_ctx, const char *strhex) 
799 {
800         DATA_BLOB ret_blob;
801
802         if (mem_ctx != NULL)
803                 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
804         else
805                 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
806
807         ret_blob.length = strhex_to_str((char*)ret_blob.data,   
808                                         strlen(strhex), 
809                                         strhex);
810
811         return ret_blob;
812 }
813
814 /**
815  * Routine to print a buffer as HEX digits, into an allocated string.
816  */
817
818 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
819 {
820         int i;
821         char *hex_buffer;
822
823         hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
824
825         for (i = 0; i < len; i++)
826                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
827
828         return hex_buffer;
829 }
830
831 /**
832  Check if a string is part of a list.
833 **/
834
835 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
836 {
837         pstring tok;
838         const char *p=list;
839
840         if (!list)
841                 return(False);
842
843         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
844                 if (casesensitive) {
845                         if (strcmp(tok,s) == 0)
846                                 return(True);
847                 } else {
848                         if (StrCaseCmp(tok,s) == 0)
849                                 return(True);
850                 }
851         }
852         return(False);
853 }
854
855 /* this is used to prevent lots of mallocs of size 1 */
856 static char *null_string = NULL;
857
858 /**
859  Set a string value, allocing the space for the string
860 **/
861
862 static BOOL string_init(char **dest,const char *src)
863 {
864         size_t l;
865         if (!src)     
866                 src = "";
867
868         l = strlen(src);
869
870         if (l == 0) {
871                 if (!null_string) {
872                         if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
873                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
874                                 return False;
875                         }
876                         *null_string = 0;
877                 }
878                 *dest = null_string;
879         } else {
880                 (*dest) = SMB_STRDUP(src);
881                 if ((*dest) == NULL) {
882                         DEBUG(0,("Out of memory in string_init\n"));
883                         return False;
884                 }
885         }
886         return(True);
887 }
888
889 /**
890  Free a string value.
891 **/
892
893 void string_free(char **s)
894 {
895         if (!s || !(*s))
896                 return;
897         if (*s == null_string)
898                 *s = NULL;
899         SAFE_FREE(*s);
900 }
901
902 /**
903  Set a string value, deallocating any existing space, and allocing the space
904  for the string
905 **/
906
907 BOOL string_set(char **dest,const char *src)
908 {
909         string_free(dest);
910         return(string_init(dest,src));
911 }
912
913 /**
914  Substitute a string for a pattern in another string. Make sure there is 
915  enough room!
916
917  This routine looks for pattern in s and replaces it with 
918  insert. It may do multiple replacements or just one.
919
920  Any of " ; ' $ or ` in the insert string are replaced with _
921  if len==0 then the string cannot be extended. This is different from the old
922  use of len==0 which was for no length checks to be done.
923 **/
924
925 void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
926                  BOOL remove_unsafe_characters, BOOL replace_once)
927 {
928         char *p;
929         ssize_t ls,lp,li, i;
930
931         if (!insert || !pattern || !*pattern || !s)
932                 return;
933
934         ls = (ssize_t)strlen(s);
935         lp = (ssize_t)strlen(pattern);
936         li = (ssize_t)strlen(insert);
937
938         if (len == 0)
939                 len = ls + 1; /* len is number of *bytes* */
940
941         while (lp <= ls && (p = strstr_m(s,pattern))) {
942                 if (ls + (li-lp) >= len) {
943                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
944                                  (int)(ls + (li-lp) - len),
945                                  pattern, (int)len));
946                         break;
947                 }
948                 if (li != lp) {
949                         memmove(p+li,p+lp,strlen(p+lp)+1);
950                 }
951                 for (i=0;i<li;i++) {
952                         switch (insert[i]) {
953                         case '`':
954                         case '"':
955                         case '\'':
956                         case ';':
957                         case '$':
958                         case '%':
959                         case '\r':
960                         case '\n':
961                                 if ( remove_unsafe_characters ) {
962                                         p[i] = '_';
963                                         /* yes this break should be here since we want to 
964                                            fall throw if not replacing unsafe chars */
965                                         break;
966                                 }
967                         default:
968                                 p[i] = insert[i];
969                         }
970                 }
971                 s = p + li;
972                 ls += (li-lp);
973
974                 if (replace_once)
975                         break;
976         }
977 }
978
979 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
980 {
981         string_sub2( s, pattern, insert, len, True, True );
982 }
983
984 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
985 {
986         string_sub2( s, pattern, insert, len, True, False );
987 }
988
989 void fstring_sub(char *s,const char *pattern,const char *insert)
990 {
991         string_sub(s, pattern, insert, sizeof(fstring));
992 }
993
994 void pstring_sub(char *s,const char *pattern,const char *insert)
995 {
996         string_sub(s, pattern, insert, sizeof(pstring));
997 }
998
999 /**
1000  Similar to string_sub, but it will accept only allocated strings
1001  and may realloc them so pay attention at what you pass on no
1002  pointers inside strings, no pstrings or const may be passed
1003  as string.
1004 **/
1005
1006 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
1007 {
1008         char *p, *in;
1009         char *s;
1010         ssize_t ls,lp,li,ld, i;
1011
1012         if (!insert || !pattern || !*pattern || !string || !*string)
1013                 return NULL;
1014
1015         s = string;
1016
1017         in = SMB_STRDUP(insert);
1018         if (!in) {
1019                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1020                 return NULL;
1021         }
1022         ls = (ssize_t)strlen(s);
1023         lp = (ssize_t)strlen(pattern);
1024         li = (ssize_t)strlen(insert);
1025         ld = li - lp;
1026         for (i=0;i<li;i++) {
1027                 switch (in[i]) {
1028                         case '`':
1029                         case '"':
1030                         case '\'':
1031                         case ';':
1032                         case '$':
1033                         case '%':
1034                         case '\r':
1035                         case '\n':
1036                                 in[i] = '_';
1037                         default:
1038                                 /* ok */
1039                                 break;
1040                 }
1041         }
1042         
1043         while ((p = strstr_m(s,pattern))) {
1044                 if (ld > 0) {
1045                         int offset = PTR_DIFF(s,string);
1046                         char *t = SMB_REALLOC(string, ls + ld + 1);
1047                         if (!t) {
1048                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1049                                 SAFE_FREE(in);
1050                                 return NULL;
1051                         }
1052                         string = t;
1053                         p = t + offset + (p - s);
1054                 }
1055                 if (li != lp) {
1056                         memmove(p+li,p+lp,strlen(p+lp)+1);
1057                 }
1058                 memcpy(p, in, li);
1059                 s = p + li;
1060                 ls += ld;
1061         }
1062         SAFE_FREE(in);
1063         return string;
1064 }
1065
1066 /**
1067  Similar to string_sub() but allows for any character to be substituted. 
1068  Use with caution!
1069  if len==0 then the string cannot be extended. This is different from the old
1070  use of len==0 which was for no length checks to be done.
1071 **/
1072
1073 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1074 {
1075         char *p;
1076         ssize_t ls,lp,li;
1077
1078         if (!insert || !pattern || !s)
1079                 return;
1080
1081         ls = (ssize_t)strlen(s);
1082         lp = (ssize_t)strlen(pattern);
1083         li = (ssize_t)strlen(insert);
1084
1085         if (!*pattern)
1086                 return;
1087         
1088         if (len == 0)
1089                 len = ls + 1; /* len is number of *bytes* */
1090         
1091         while (lp <= ls && (p = strstr_m(s,pattern))) {
1092                 if (ls + (li-lp) >= len) {
1093                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1094                                  (int)(ls + (li-lp) - len),
1095                                  pattern, (int)len));
1096                         break;
1097                 }
1098                 if (li != lp) {
1099                         memmove(p+li,p+lp,strlen(p+lp)+1);
1100                 }
1101                 memcpy(p, insert, li);
1102                 s = p + li;
1103                 ls += (li-lp);
1104         }
1105 }
1106
1107 /**
1108  Similar to all_string_sub but for unicode strings.
1109  Return a new allocated unicode string.
1110  similar to string_sub() but allows for any character to be substituted.
1111  Use with caution!
1112 **/
1113
1114 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1115                                 const smb_ucs2_t *insert)
1116 {
1117         smb_ucs2_t *r, *rp;
1118         const smb_ucs2_t *sp;
1119         size_t  lr, lp, li, lt;
1120
1121         if (!insert || !pattern || !*pattern || !s)
1122                 return NULL;
1123
1124         lt = (size_t)strlen_w(s);
1125         lp = (size_t)strlen_w(pattern);
1126         li = (size_t)strlen_w(insert);
1127
1128         if (li > lp) {
1129                 const smb_ucs2_t *st = s;
1130                 int ld = li - lp;
1131                 while ((sp = strstr_w(st, pattern))) {
1132                         st = sp + lp;
1133                         lt += ld;
1134                 }
1135         }
1136
1137         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1138         if (!r) {
1139                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1140                 return NULL;
1141         }
1142
1143         while ((sp = strstr_w(s, pattern))) {
1144                 memcpy(rp, s, (sp - s));
1145                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1146                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1147                 s = sp + lp;
1148                 rp += li;
1149         }
1150         lr = ((rp - r) / sizeof(smb_ucs2_t));
1151         if (lr < lt) {
1152                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1153                 rp += (lt - lr);
1154         }
1155         *rp = 0;
1156
1157         return r;
1158 }
1159
1160 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1161                                              const char *insert)
1162 {
1163         wpstring p, i;
1164
1165         if (!insert || !pattern || !s)
1166                 return NULL;
1167         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1168         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1169         return all_string_sub_w(s, p, i);
1170 }
1171
1172 #if 0
1173 /**
1174  Splits out the front and back at a separator.
1175 **/
1176
1177 static void split_at_last_component(char *path, char *front, char sep, char *back)
1178 {
1179         char *p = strrchr_m(path, sep);
1180
1181         if (p != NULL)
1182                 *p = 0;
1183
1184         if (front != NULL)
1185                 pstrcpy(front, path);
1186
1187         if (p != NULL) {
1188                 if (back != NULL)
1189                         pstrcpy(back, p+1);
1190                 *p = '\\';
1191         } else {
1192                 if (back != NULL)
1193                         back[0] = 0;
1194         }
1195 }
1196 #endif
1197
1198 /**
1199  Write an octal as a string.
1200 **/
1201
1202 const char *octal_string(int i)
1203 {
1204         static char ret[64];
1205         if (i == -1)
1206                 return "-1";
1207         slprintf(ret, sizeof(ret)-1, "0%o", i);
1208         return ret;
1209 }
1210
1211
1212 /**
1213  Truncate a string at a specified length.
1214 **/
1215
1216 char *string_truncate(char *s, unsigned int length)
1217 {
1218         if (s && strlen(s) > length)
1219                 s[length] = 0;
1220         return s;
1221 }
1222
1223 /**
1224  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1225  We convert via ucs2 for now.
1226 **/
1227
1228 char *strchr_m(const char *src, char c)
1229 {
1230         wpstring ws;
1231         pstring s2;
1232         smb_ucs2_t *p;
1233         const char *s;
1234
1235         /* characters below 0x3F are guaranteed to not appear in
1236            non-initial position in multi-byte charsets */
1237         if ((c & 0xC0) == 0) {
1238                 return strchr(src, c);
1239         }
1240
1241         /* this is quite a common operation, so we want it to be
1242            fast. We optimise for the ascii case, knowing that all our
1243            supported multi-byte character sets are ascii-compatible
1244            (ie. they match for the first 128 chars) */
1245
1246         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1247                 if (*s == c)
1248                         return (char *)s;
1249         }
1250
1251         if (!*s)
1252                 return NULL;
1253
1254 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1255         /* With compose characters we must restart from the beginning. JRA. */
1256         s = src;
1257 #endif
1258
1259         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1260         p = strchr_w(ws, UCS2_CHAR(c));
1261         if (!p)
1262                 return NULL;
1263         *p = 0;
1264         pull_ucs2_pstring(s2, ws);
1265         return (char *)(s+strlen(s2));
1266 }
1267
1268 char *strrchr_m(const char *s, char c)
1269 {
1270         /* characters below 0x3F are guaranteed to not appear in
1271            non-initial position in multi-byte charsets */
1272         if ((c & 0xC0) == 0) {
1273                 return strrchr(s, c);
1274         }
1275
1276         /* this is quite a common operation, so we want it to be
1277            fast. We optimise for the ascii case, knowing that all our
1278            supported multi-byte character sets are ascii-compatible
1279            (ie. they match for the first 128 chars). Also, in Samba
1280            we only search for ascii characters in 'c' and that
1281            in all mb character sets with a compound character
1282            containing c, if 'c' is not a match at position
1283            p, then p[-1] > 0x7f. JRA. */
1284
1285         {
1286                 size_t len = strlen(s);
1287                 const char *cp = s;
1288                 BOOL got_mb = False;
1289
1290                 if (len == 0)
1291                         return NULL;
1292                 cp += (len - 1);
1293                 do {
1294                         if (c == *cp) {
1295                                 /* Could be a match. Part of a multibyte ? */
1296                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1297                                         /* Yep - go slow :-( */
1298                                         got_mb = True;
1299                                         break;
1300                                 }
1301                                 /* No - we have a match ! */
1302                                 return (char *)cp;
1303                         }
1304                 } while (cp-- != s);
1305                 if (!got_mb)
1306                         return NULL;
1307         }
1308
1309         /* String contained a non-ascii char. Slow path. */
1310         {
1311                 wpstring ws;
1312                 pstring s2;
1313                 smb_ucs2_t *p;
1314
1315                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1316                 p = strrchr_w(ws, UCS2_CHAR(c));
1317                 if (!p)
1318                         return NULL;
1319                 *p = 0;
1320                 pull_ucs2_pstring(s2, ws);
1321                 return (char *)(s+strlen(s2));
1322         }
1323 }
1324
1325 /***********************************************************************
1326  Return the equivalent of doing strrchr 'n' times - always going
1327  backwards.
1328 ***********************************************************************/
1329
1330 char *strnrchr_m(const char *s, char c, unsigned int n)
1331 {
1332         wpstring ws;
1333         pstring s2;
1334         smb_ucs2_t *p;
1335
1336         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1337         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1338         if (!p)
1339                 return NULL;
1340         *p = 0;
1341         pull_ucs2_pstring(s2, ws);
1342         return (char *)(s+strlen(s2));
1343 }
1344
1345 /***********************************************************************
1346  strstr_m - We convert via ucs2 for now.
1347 ***********************************************************************/
1348
1349 char *strstr_m(const char *src, const char *findstr)
1350 {
1351         smb_ucs2_t *p;
1352         smb_ucs2_t *src_w, *find_w;
1353         const char *s;
1354         char *s2;
1355         char *retp;
1356
1357         size_t findstr_len = 0;
1358
1359         /* for correctness */
1360         if (!findstr[0]) {
1361                 return (char*)src;
1362         }
1363
1364         /* Samba does single character findstr calls a *lot*. */
1365         if (findstr[1] == '\0')
1366                 return strchr_m(src, *findstr);
1367
1368         /* We optimise for the ascii case, knowing that all our
1369            supported multi-byte character sets are ascii-compatible
1370            (ie. they match for the first 128 chars) */
1371
1372         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1373                 if (*s == *findstr) {
1374                         if (!findstr_len) 
1375                                 findstr_len = strlen(findstr);
1376
1377                         if (strncmp(s, findstr, findstr_len) == 0) {
1378                                 return (char *)s;
1379                         }
1380                 }
1381         }
1382
1383         if (!*s)
1384                 return NULL;
1385
1386 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1387         /* 'make check' fails unless we do this */
1388
1389         /* With compose characters we must restart from the beginning. JRA. */
1390         s = src;
1391 #endif
1392
1393         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1394                 DEBUG(0,("strstr_m: src malloc fail\n"));
1395                 return NULL;
1396         }
1397         
1398         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1399                 SAFE_FREE(src_w);
1400                 DEBUG(0,("strstr_m: find malloc fail\n"));
1401                 return NULL;
1402         }
1403
1404         p = strstr_w(src_w, find_w);
1405
1406         if (!p) {
1407                 SAFE_FREE(src_w);
1408                 SAFE_FREE(find_w);
1409                 return NULL;
1410         }
1411         
1412         *p = 0;
1413         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1414                 SAFE_FREE(src_w);
1415                 SAFE_FREE(find_w);
1416                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1417                 return NULL;
1418         }
1419         retp = (char *)(s+strlen(s2));
1420         SAFE_FREE(src_w);
1421         SAFE_FREE(find_w);
1422         SAFE_FREE(s2);
1423         return retp;
1424 }
1425
1426 /**
1427  Convert a string to lower case.
1428 **/
1429
1430 void strlower_m(char *s)
1431 {
1432         size_t len;
1433         int errno_save;
1434
1435         /* this is quite a common operation, so we want it to be
1436            fast. We optimise for the ascii case, knowing that all our
1437            supported multi-byte character sets are ascii-compatible
1438            (ie. they match for the first 128 chars) */
1439
1440         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1441                 *s = tolower((unsigned char)*s);
1442                 s++;
1443         }
1444
1445         if (!*s)
1446                 return;
1447
1448         /* I assume that lowercased string takes the same number of bytes
1449          * as source string even in UTF-8 encoding. (VIV) */
1450         len = strlen(s) + 1;
1451         errno_save = errno;
1452         errno = 0;
1453         unix_strlower(s,len,s,len);     
1454         /* Catch mb conversion errors that may not terminate. */
1455         if (errno)
1456                 s[len-1] = '\0';
1457         errno = errno_save;
1458 }
1459
1460 /**
1461  Convert a string to upper case.
1462 **/
1463
1464 void strupper_m(char *s)
1465 {
1466         size_t len;
1467         int errno_save;
1468
1469         /* this is quite a common operation, so we want it to be
1470            fast. We optimise for the ascii case, knowing that all our
1471            supported multi-byte character sets are ascii-compatible
1472            (ie. they match for the first 128 chars) */
1473
1474         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1475                 *s = toupper((unsigned char)*s);
1476                 s++;
1477         }
1478
1479         if (!*s)
1480                 return;
1481
1482         /* I assume that lowercased string takes the same number of bytes
1483          * as source string even in multibyte encoding. (VIV) */
1484         len = strlen(s) + 1;
1485         errno_save = errno;
1486         errno = 0;
1487         unix_strupper(s,len,s,len);     
1488         /* Catch mb conversion errors that may not terminate. */
1489         if (errno)
1490                 s[len-1] = '\0';
1491         errno = errno_save;
1492 }
1493
1494 /**
1495  Return a RFC2254 binary string representation of a buffer.
1496  Used in LDAP filters.
1497  Caller must free.
1498 **/
1499
1500 char *binary_string(char *buf, int len)
1501 {
1502         char *s;
1503         int i, j;
1504         const char *hex = "0123456789ABCDEF";
1505         s = SMB_MALLOC(len * 3 + 1);
1506         if (!s)
1507                 return NULL;
1508         for (j=i=0;i<len;i++) {
1509                 s[j] = '\\';
1510                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1511                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1512                 j += 3;
1513         }
1514         s[j] = 0;
1515         return s;
1516 }
1517
1518 /**
1519  Just a typesafety wrapper for snprintf into a pstring.
1520 **/
1521
1522  int pstr_sprintf(pstring s, const char *fmt, ...)
1523 {
1524         va_list ap;
1525         int ret;
1526
1527         va_start(ap, fmt);
1528         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1529         va_end(ap);
1530         return ret;
1531 }
1532
1533
1534 /**
1535  Just a typesafety wrapper for snprintf into a fstring.
1536 **/
1537
1538 int fstr_sprintf(fstring s, const char *fmt, ...)
1539 {
1540         va_list ap;
1541         int ret;
1542
1543         va_start(ap, fmt);
1544         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1545         va_end(ap);
1546         return ret;
1547 }
1548
1549
1550 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1551 /**
1552  Some platforms don't have strndup.
1553 **/
1554 #if defined(PARANOID_MALLOC_CHECKER)
1555 #undef strndup
1556 #endif
1557
1558  char *strndup(const char *s, size_t n)
1559 {
1560         char *ret;
1561         
1562         n = strnlen(s, n);
1563         ret = SMB_MALLOC(n+1);
1564         if (!ret)
1565                 return NULL;
1566         memcpy(ret, s, n);
1567         ret[n] = 0;
1568
1569         return ret;
1570 }
1571
1572 #if defined(PARANOID_MALLOC_CHECKER)
1573 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1574 #endif
1575
1576 #endif
1577
1578 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1579 /**
1580  Some platforms don't have strnlen
1581 **/
1582
1583  size_t strnlen(const char *s, size_t n)
1584 {
1585         size_t i;
1586         for (i=0; i<n && s[i] != '\0'; i++)
1587                 /* noop */ ;
1588         return i;
1589 }
1590 #endif
1591
1592 /**
1593  List of Strings manipulation functions
1594 **/
1595
1596 #define S_LIST_ABS 16 /* List Allocation Block Size */
1597
1598 char **str_list_make(const char *string, const char *sep)
1599 {
1600         char **list, **rlist;
1601         const char *str;
1602         char *s;
1603         int num, lsize;
1604         pstring tok;
1605         
1606         if (!string || !*string)
1607                 return NULL;
1608         s = SMB_STRDUP(string);
1609         if (!s) {
1610                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1611                 return NULL;
1612         }
1613         if (!sep) sep = LIST_SEP;
1614         
1615         num = lsize = 0;
1616         list = NULL;
1617         
1618         str = s;
1619         while (next_token(&str, tok, sep, sizeof(tok))) {               
1620                 if (num == lsize) {
1621                         lsize += S_LIST_ABS;
1622                         rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1623                         if (!rlist) {
1624                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1625                                 str_list_free(&list);
1626                                 SAFE_FREE(s);
1627                                 return NULL;
1628                         } else
1629                                 list = rlist;
1630                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1631                 }
1632                 
1633                 list[num] = SMB_STRDUP(tok);
1634                 if (!list[num]) {
1635                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1636                         str_list_free(&list);
1637                         SAFE_FREE(s);
1638                         return NULL;
1639                 }
1640         
1641                 num++;  
1642         }
1643         
1644         SAFE_FREE(s);
1645         return list;
1646 }
1647
1648 BOOL str_list_copy(char ***dest, const char **src)
1649 {
1650         char **list, **rlist;
1651         int num, lsize;
1652         
1653         *dest = NULL;
1654         if (!src)
1655                 return False;
1656         
1657         num = lsize = 0;
1658         list = NULL;
1659                 
1660         while (src[num]) {
1661                 if (num == lsize) {
1662                         lsize += S_LIST_ABS;
1663                         rlist = SMB_REALLOC_ARRAY(list, char *, lsize +1);
1664                         if (!rlist) {
1665                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1666                                 str_list_free(&list);
1667                                 return False;
1668                         } else
1669                                 list = rlist;
1670                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1671                 }
1672                 
1673                 list[num] = SMB_STRDUP(src[num]);
1674                 if (!list[num]) {
1675                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1676                         str_list_free(&list);
1677                         return False;
1678                 }
1679
1680                 num++;
1681         }
1682         
1683         *dest = list;
1684         return True;    
1685 }
1686
1687 /**
1688  * Return true if all the elements of the list match exactly.
1689  **/
1690 BOOL str_list_compare(char **list1, char **list2)
1691 {
1692         int num;
1693         
1694         if (!list1 || !list2)
1695                 return (list1 == list2); 
1696         
1697         for (num = 0; list1[num]; num++) {
1698                 if (!list2[num])
1699                         return False;
1700                 if (!strcsequal(list1[num], list2[num]))
1701                         return False;
1702         }
1703         if (list2[num])
1704                 return False; /* if list2 has more elements than list1 fail */
1705         
1706         return True;
1707 }
1708
1709 void str_list_free(char ***list)
1710 {
1711         char **tlist;
1712         
1713         if (!list || !*list)
1714                 return;
1715         tlist = *list;
1716         for(; *tlist; tlist++)
1717                 SAFE_FREE(*tlist);
1718         SAFE_FREE(*list);
1719 }
1720
1721 /******************************************************************************
1722  *****************************************************************************/
1723
1724 int str_list_count( const char **list )
1725 {
1726         int i = 0;
1727
1728         /* count the number of list members */
1729         
1730         for ( i=0; *list; i++, list++ );
1731         
1732         return i;
1733 }
1734
1735 /******************************************************************************
1736  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1737  for the work
1738  *****************************************************************************/
1739  
1740 BOOL str_list_sub_basic( char **list, const char *smb_name )
1741 {
1742         char *s, *tmpstr;
1743         
1744         while ( *list ) {
1745                 s = *list;
1746                 tmpstr = alloc_sub_basic(smb_name, s);
1747                 if ( !tmpstr ) {
1748                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1749                         return False;
1750                 }
1751
1752                 SAFE_FREE(*list);
1753                 *list = tmpstr;
1754                         
1755                 list++;
1756         }
1757
1758         return True;
1759 }
1760
1761 /******************************************************************************
1762  substritute a specific pattern in a string list
1763  *****************************************************************************/
1764  
1765 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1766 {
1767         char *p, *s, *t;
1768         ssize_t ls, lp, li, ld, i, d;
1769
1770         if (!list)
1771                 return False;
1772         if (!pattern)
1773                 return False;
1774         if (!insert)
1775                 return False;
1776
1777         lp = (ssize_t)strlen(pattern);
1778         li = (ssize_t)strlen(insert);
1779         ld = li -lp;
1780                         
1781         while (*list) {
1782                 s = *list;
1783                 ls = (ssize_t)strlen(s);
1784
1785                 while ((p = strstr_m(s, pattern))) {
1786                         t = *list;
1787                         d = p -t;
1788                         if (ld) {
1789                                 t = (char *) SMB_MALLOC(ls +ld +1);
1790                                 if (!t) {
1791                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1792                                         return False;
1793                                 }
1794                                 memcpy(t, *list, d);
1795                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1796                                 SAFE_FREE(*list);
1797                                 *list = t;
1798                                 ls += ld;
1799                                 s = t +d +li;
1800                         }
1801                         
1802                         for (i = 0; i < li; i++) {
1803                                 switch (insert[i]) {
1804                                         case '`':
1805                                         case '"':
1806                                         case '\'':
1807                                         case ';':
1808                                         case '$':
1809                                         case '%':
1810                                         case '\r':
1811                                         case '\n':
1812                                                 t[d +i] = '_';
1813                                                 break;
1814                                         default:
1815                                                 t[d +i] = insert[i];
1816                                 }
1817                         }       
1818                 }
1819                 
1820                 
1821                 list++;
1822         }
1823         
1824         return True;
1825 }
1826
1827
1828 #define IPSTR_LIST_SEP  ","
1829 #define IPSTR_LIST_CHAR ','
1830
1831 /**
1832  * Add ip string representation to ipstr list. Used also
1833  * as part of @function ipstr_list_make
1834  *
1835  * @param ipstr_list pointer to string containing ip list;
1836  *        MUST BE already allocated and IS reallocated if necessary
1837  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1838  *        as a result of reallocation)
1839  * @param ip IP address which is to be added to list
1840  * @return pointer to string appended with new ip and possibly
1841  *         reallocated to new length
1842  **/
1843
1844 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1845 {
1846         char* new_ipstr = NULL;
1847         
1848         /* arguments checking */
1849         if (!ipstr_list || !service) return NULL;
1850
1851         /* attempt to convert ip to a string and append colon separator to it */
1852         if (*ipstr_list) {
1853                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1854                         inet_ntoa(service->ip), service->port);
1855                 SAFE_FREE(*ipstr_list);
1856         } else {
1857                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1858         }
1859         *ipstr_list = new_ipstr;
1860         return *ipstr_list;
1861 }
1862
1863
1864 /**
1865  * Allocate and initialise an ipstr list using ip adresses
1866  * passed as arguments.
1867  *
1868  * @param ipstr_list pointer to string meant to be allocated and set
1869  * @param ip_list array of ip addresses to place in the list
1870  * @param ip_count number of addresses stored in ip_list
1871  * @return pointer to allocated ip string
1872  **/
1873  
1874 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1875 {
1876         int i;
1877         
1878         /* arguments checking */
1879         if (!ip_list && !ipstr_list) return 0;
1880
1881         *ipstr_list = NULL;
1882         
1883         /* process ip addresses given as arguments */
1884         for (i = 0; i < ip_count; i++)
1885                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1886         
1887         return (*ipstr_list);
1888 }
1889
1890
1891 /**
1892  * Parse given ip string list into array of ip addresses
1893  * (as ip_service structures)  
1894  *    e.g. 192.168.1.100:389,192.168.1.78, ...
1895  *
1896  * @param ipstr ip string list to be parsed 
1897  * @param ip_list pointer to array of ip addresses which is
1898  *        allocated by this function and must be freed by caller
1899  * @return number of succesfully parsed addresses
1900  **/
1901  
1902 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1903 {
1904         fstring token_str;
1905         size_t count;
1906         int i;
1907
1908         if (!ipstr_list || !ip_list) 
1909                 return 0;
1910         
1911         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1912         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1913                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1914                 return 0;
1915         }
1916         
1917         for ( i=0; 
1918                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
1919                 i++ ) 
1920         {
1921                 struct in_addr addr;
1922                 unsigned port = 0;      
1923                 char *p = strchr(token_str, ':');
1924                 
1925                 if (p) {
1926                         *p = 0;
1927                         port = atoi(p+1);
1928                 }
1929
1930                 /* convert single token to ip address */
1931                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1932                         break;
1933                                 
1934                 (*ip_list)[i].ip = addr;
1935                 (*ip_list)[i].port = port;
1936         }
1937         
1938         return count;
1939 }
1940
1941
1942 /**
1943  * Safely free ip string list
1944  *
1945  * @param ipstr_list ip string list to be freed
1946  **/
1947
1948 void ipstr_list_free(char* ipstr_list)
1949 {
1950         SAFE_FREE(ipstr_list);
1951 }
1952
1953
1954 /**
1955  Unescape a URL encoded string, in place.
1956 **/
1957
1958 void rfc1738_unescape(char *buf)
1959 {
1960         char *p=buf;
1961
1962         while (p && *p && (p=strchr_m(p,'%'))) {
1963                 int c1 = p[1];
1964                 int c2 = p[2];
1965
1966                 if (c1 >= '0' && c1 <= '9')
1967                         c1 = c1 - '0';
1968                 else if (c1 >= 'A' && c1 <= 'F')
1969                         c1 = 10 + c1 - 'A';
1970                 else if (c1 >= 'a' && c1 <= 'f')
1971                         c1 = 10 + c1 - 'a';
1972                 else {p++; continue;}
1973
1974                 if (c2 >= '0' && c2 <= '9')
1975                         c2 = c2 - '0';
1976                 else if (c2 >= 'A' && c2 <= 'F')
1977                         c2 = 10 + c2 - 'A';
1978                 else if (c2 >= 'a' && c2 <= 'f')
1979                         c2 = 10 + c2 - 'a';
1980                 else {p++; continue;}
1981                         
1982                 *p = (c1<<4) | c2;
1983
1984                 memmove(p+1, p+3, strlen(p+3)+1);
1985                 p++;
1986         }
1987 }
1988
1989 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1990
1991 /**
1992  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1993  **/
1994 DATA_BLOB base64_decode_data_blob(const char *s)
1995 {
1996         int bit_offset, byte_offset, idx, i, n;
1997         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1998         unsigned char *d = decoded.data;
1999         char *p;
2000
2001         n=i=0;
2002
2003         while (*s && (p=strchr_m(b64,*s))) {
2004                 idx = (int)(p - b64);
2005                 byte_offset = (i*6)/8;
2006                 bit_offset = (i*6)%8;
2007                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2008                 if (bit_offset < 3) {
2009                         d[byte_offset] |= (idx << (2-bit_offset));
2010                         n = byte_offset+1;
2011                 } else {
2012                         d[byte_offset] |= (idx >> (bit_offset-2));
2013                         d[byte_offset+1] = 0;
2014                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2015                         n = byte_offset+2;
2016                 }
2017                 s++; i++;
2018         }
2019
2020         if ((n > 0) && (*s == '=')) {
2021                 n -= 1;
2022         }
2023
2024         /* fix up length */
2025         decoded.length = n;
2026         return decoded;
2027 }
2028
2029 /**
2030  * Decode a base64 string in-place - wrapper for the above
2031  **/
2032 void base64_decode_inplace(char *s)
2033 {
2034         DATA_BLOB decoded = base64_decode_data_blob(s);
2035
2036         if ( decoded.length != 0 ) {
2037                 memcpy(s, decoded.data, decoded.length);
2038
2039                 /* null terminate */
2040                 s[decoded.length] = '\0';
2041         } else {
2042                 *s = '\0';
2043         }
2044
2045         data_blob_free(&decoded);
2046 }
2047
2048 /**
2049  * Encode a base64 string into a malloc()ed string caller to free.
2050  *
2051  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2052  **/
2053 char * base64_encode_data_blob(DATA_BLOB data)
2054 {
2055         int bits = 0;
2056         int char_count = 0;
2057         size_t out_cnt, len, output_len;
2058         char *result;
2059
2060         if (!data.length || !data.data)
2061                 return NULL;
2062
2063         out_cnt = 0;
2064         len = data.length;
2065         output_len = data.length * 2;
2066         result = SMB_MALLOC(output_len); /* get us plenty of space */
2067
2068         while (len-- && out_cnt < (data.length * 2) - 5) {
2069                 int c = (unsigned char) *(data.data++);
2070                 bits += c;
2071                 char_count++;
2072                 if (char_count == 3) {
2073                         result[out_cnt++] = b64[bits >> 18];
2074                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2075                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2076             result[out_cnt++] = b64[bits & 0x3f];
2077             bits = 0;
2078             char_count = 0;
2079         } else {
2080             bits <<= 8;
2081         }
2082     }
2083     if (char_count != 0) {
2084         bits <<= 16 - (8 * char_count);
2085         result[out_cnt++] = b64[bits >> 18];
2086         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2087         if (char_count == 1) {
2088             result[out_cnt++] = '=';
2089             result[out_cnt++] = '=';
2090         } else {
2091             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2092             result[out_cnt++] = '=';
2093         }
2094     }
2095     result[out_cnt] = '\0';     /* terminate */
2096     return result;
2097 }
2098
2099 /* read a SMB_BIG_UINT from a string */
2100 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2101 {
2102
2103         SMB_BIG_UINT val = -1;
2104         const char *p = nptr;
2105         
2106         while (p && *p && isspace(*p))
2107                 p++;
2108 #ifdef LARGE_SMB_OFF_T
2109         sscanf(p,"%llu",&val);  
2110 #else /* LARGE_SMB_OFF_T */
2111         sscanf(p,"%lu",&val);
2112 #endif /* LARGE_SMB_OFF_T */
2113         if (entptr) {
2114                 while (p && *p && isdigit(*p))
2115                         p++;
2116                 *entptr = p;
2117         }
2118
2119         return val;
2120 }
2121
2122 void string_append(char **left, const char *right)
2123 {
2124         int new_len = strlen(right) + 1;
2125
2126         if (*left == NULL) {
2127                 *left = SMB_MALLOC(new_len);
2128                 *left[0] = '\0';
2129         } else {
2130                 new_len += strlen(*left);
2131                 *left = SMB_REALLOC(*left, new_len);
2132         }
2133
2134         if (*left == NULL)
2135                 return;
2136
2137         safe_strcat(*left, right, new_len-1);
2138 }
2139
2140 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2141                          const char *str, const char ***strings,
2142                          int *num)
2143 {
2144         char *dup_str = talloc_strdup(mem_ctx, str);
2145
2146         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2147
2148         if ((*strings == NULL) || (dup_str == NULL))
2149                 return False;
2150
2151         (*strings)[*num] = dup_str;
2152         *num += 1;
2153         return True;
2154 }
2155
2156 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2157  * error checking in between. The indiation that something weird happened is
2158  * string==NULL */
2159
2160 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2161                     size_t *bufsize, const char *fmt, ...)
2162 {
2163         va_list ap;
2164         char *newstr;
2165         int ret;
2166         BOOL increased;
2167
2168         /* len<0 is an internal marker that something failed */
2169         if (*len < 0)
2170                 goto error;
2171
2172         if (*string == NULL) {
2173                 if (*bufsize == 0)
2174                         *bufsize = 128;
2175
2176                 if (mem_ctx != NULL)
2177                         *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2178                 else
2179                         *string = SMB_MALLOC_ARRAY(char, *bufsize);
2180
2181                 if (*string == NULL)
2182                         goto error;
2183         }
2184
2185         va_start(ap, fmt);
2186         ret = vasprintf(&newstr, fmt, ap);
2187         va_end(ap);
2188
2189         if (ret < 0)
2190                 goto error;
2191
2192         increased = False;
2193
2194         while ((*len)+ret >= *bufsize) {
2195                 increased = True;
2196                 *bufsize *= 2;
2197                 if (*bufsize >= (1024*1024*256))
2198                         goto error;
2199         }
2200
2201         if (increased) {
2202                 if (mem_ctx != NULL)
2203                         *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2204                                                        *bufsize);
2205                 else
2206                         *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2207
2208                 if (*string == NULL)
2209                         goto error;
2210         }
2211
2212         StrnCpy((*string)+(*len), newstr, ret);
2213         (*len) += ret;
2214         free(newstr);
2215         return;
2216
2217  error:
2218         *len = -1;
2219         *string = NULL;
2220 }
2221
2222 /*
2223    Returns the substring from src between the first occurrence of
2224    the char "front" and the first occurence of the char "back".
2225    Mallocs the return string which must be freed.  Not for use
2226    with wide character strings.
2227 */
2228 char *sstring_sub(const char *src, char front, char back)
2229 {
2230         char *temp1, *temp2, *temp3;
2231         ptrdiff_t len;
2232
2233         temp1 = strchr(src, front);
2234         if (temp1 == NULL) return NULL;
2235         temp2 = strchr(src, back);
2236         if (temp2 == NULL) return NULL;
2237         len = temp2 - temp1;
2238         if (len <= 0) return NULL;
2239         temp3 = (char*)SMB_MALLOC(len);
2240         if (temp3 == NULL) {
2241                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2242                 return NULL;
2243         }
2244         memcpy(temp3, temp1+1, len-1);
2245         temp3[len-1] = '\0';
2246         return temp3;
2247 }