Update comment: Valgrind 1.9.4 seems to always respect client
[samba.git] / source3 / lib / util_str.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-2001
5    Copyright (C) Simo Sorce      2001-2002
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 #ifdef DEVELOPER
25 const char *global_clobber_region_function;
26 unsigned int global_clobber_region_line;
27 #endif
28
29 /**
30  * Get the next token from a string, return False if none found.
31  * Handles double-quotes.
32  * 
33  * Based on a routine by GJC@VILLAGE.COM. 
34  * Extensively modified by Andrew.Tridgell@anu.edu.au
35  **/
36 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
37 {
38         const char *s;
39         BOOL quoted;
40         size_t len=1;
41
42         if (!ptr)
43                 return(False);
44
45         s = *ptr;
46
47         /* default to simple separators */
48         if (!sep)
49                 sep = " \t\n\r";
50
51         /* find the first non sep char */
52         while (*s && strchr_m(sep,*s))
53                 s++;
54         
55         /* nothing left? */
56         if (! *s)
57                 return(False);
58         
59         /* copy over the token */
60         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
61                 if (*s == '\"') {
62                         quoted = !quoted;
63                 } else {
64                         len++;
65                         *buff++ = *s;
66                 }
67         }
68         
69         *ptr = (*s) ? s+1 : s;  
70         *buff = 0;
71         
72         return(True);
73 }
74
75 /**
76 This is like next_token but is not re-entrant and "remembers" the first 
77 parameter so you can pass NULL. This is useful for user interface code
78 but beware the fact that it is not re-entrant!
79 **/
80
81 static const char *last_ptr=NULL;
82
83 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
84 {
85         BOOL ret;
86         if (!ptr)
87                 ptr = (const char **)&last_ptr;
88
89         ret = next_token(ptr, buff, sep, bufsize);
90         last_ptr = *ptr;
91         return ret;     
92 }
93
94 static uint16 tmpbuf[sizeof(pstring)];
95
96 void set_first_token(char *ptr)
97 {
98         last_ptr = ptr;
99 }
100
101 /**
102  Convert list of tokens to array; dependent on above routine.
103  Uses last_ptr from above - bit of a hack.
104 **/
105
106 char **toktocliplist(int *ctok, const char *sep)
107 {
108         char *s=last_ptr;
109         int ictok=0;
110         char **ret, **iret;
111
112         if (!sep)
113                 sep = " \t\n\r";
114
115         while(*s && strchr_m(sep,*s))
116                 s++;
117
118         /* nothing left? */
119         if (!*s)
120                 return(NULL);
121
122         do {
123                 ictok++;
124                 while(*s && (!strchr_m(sep,*s)))
125                         s++;
126                 while(*s && strchr_m(sep,*s))
127                         *s++=0;
128         } while(*s);
129         
130         *ctok=ictok;
131         s=last_ptr;
132         
133         if (!(ret=iret=malloc(ictok*sizeof(char *))))
134                 return NULL;
135         
136         while(ictok--) {    
137                 *iret++=s;
138                 while(*s++)
139                         ;
140                 while(!*s)
141                         s++;
142         }
143
144         return ret;
145 }
146
147 /**
148  Case insensitive string compararison.
149 **/
150
151 int StrCaseCmp(const char *s, const char *t)
152 {
153         pstring buf1, buf2;
154         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
155         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
156         return strcmp(buf1,buf2);
157 }
158
159 /**
160  Case insensitive string compararison, length limited.
161 **/
162
163 int StrnCaseCmp(const char *s, const char *t, size_t n)
164 {
165         pstring buf1, buf2;
166         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
167         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
168         return strncmp(buf1,buf2,n);
169 }
170
171 /**
172  * Compare 2 strings.
173  *
174  * @note The comparison is case-insensitive.
175  **/
176 BOOL strequal(const char *s1, const char *s2)
177 {
178         if (s1 == s2)
179                 return(True);
180         if (!s1 || !s2)
181                 return(False);
182   
183         return(StrCaseCmp(s1,s2)==0);
184 }
185
186 /**
187  * Compare 2 strings up to and including the nth char.
188  *
189  * @note The comparison is case-insensitive.
190  **/
191 BOOL strnequal(const char *s1,const char *s2,size_t n)
192 {
193   if (s1 == s2)
194           return(True);
195   if (!s1 || !s2 || !n)
196           return(False);
197   
198   return(StrnCaseCmp(s1,s2,n)==0);
199 }
200
201 /**
202  Compare 2 strings (case sensitive).
203 **/
204
205 BOOL strcsequal(const char *s1,const char *s2)
206 {
207   if (s1 == s2)
208           return(True);
209   if (!s1 || !s2)
210           return(False);
211   
212   return(strcmp(s1,s2)==0);
213 }
214
215 /**
216 Do a case-insensitive, whitespace-ignoring string compare.
217 **/
218
219 int strwicmp(const char *psz1, const char *psz2)
220 {
221         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
222         /* appropriate value. */
223         if (psz1 == psz2)
224                 return (0);
225         else if (psz1 == NULL)
226                 return (-1);
227         else if (psz2 == NULL)
228                 return (1);
229
230         /* sync the strings on first non-whitespace */
231         while (1) {
232                 while (isspace((int)*psz1))
233                         psz1++;
234                 while (isspace((int)*psz2))
235                         psz2++;
236                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
237                     || *psz2 == '\0')
238                         break;
239                 psz1++;
240                 psz2++;
241         }
242         return (*psz1 - *psz2);
243 }
244
245
246 /**
247  Convert a string to upper case, but don't modify it.
248 **/
249
250 char *strupper_static(const char *s)
251 {
252         static pstring str;
253
254         pstrcpy(str, s);
255         strupper(str);
256
257         return str;
258 }
259
260 /**
261  Convert a string to "normal" form.
262 **/
263
264 void strnorm(char *s)
265 {
266         extern int case_default;
267         if (case_default == CASE_UPPER)
268                 strupper(s);
269         else
270                 strlower(s);
271 }
272
273 /**
274  Check if a string is in "normal" case.
275 **/
276
277 BOOL strisnormal(const char *s)
278 {
279         extern int case_default;
280         if (case_default == CASE_UPPER)
281                 return(!strhaslower(s));
282         
283         return(!strhasupper(s));
284 }
285
286
287 /**
288  String replace.
289  NOTE: oldc and newc must be 7 bit characters
290 **/
291
292 void string_replace(char *s,char oldc,char newc)
293 {
294         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
295         string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
296         pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
297 }
298
299 /**
300  Skip past some strings in a buffer.
301 **/
302
303 char *skip_string(char *buf,size_t n)
304 {
305         while (n--)
306                 buf += strlen(buf) + 1;
307         return(buf);
308 }
309
310 /**
311  Count the number of characters in a string. Normally this will
312  be the same as the number of bytes in a string for single byte strings,
313  but will be different for multibyte.
314 **/
315
316 size_t str_charnum(const char *s)
317 {
318         uint16 tmpbuf2[sizeof(pstring)];
319         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
320         return strlen_w(tmpbuf2);
321 }
322
323 /**
324  Count the number of characters in a string. Normally this will
325  be the same as the number of bytes in a string for single byte strings,
326  but will be different for multibyte.
327 **/
328
329 size_t str_ascii_charnum(const char *s)
330 {
331         pstring tmpbuf2;
332         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
333         return strlen(tmpbuf2);
334 }
335
336 /**
337  Trim the specified elements off the front and back of a string.
338 **/
339
340 BOOL trim_string(char *s,const char *front,const char *back)
341 {
342         BOOL ret = False;
343         size_t front_len;
344         size_t back_len;
345         size_t len;
346
347         /* Ignore null or empty strings. */
348         if (!s || (s[0] == '\0'))
349                 return False;
350
351         front_len       = front? strlen(front) : 0;
352         back_len        = back? strlen(back) : 0;
353
354         len = strlen(s);
355
356         if (front_len) {
357                 while (len && strncmp(s, front, front_len)==0) {
358                         memcpy(s, s+front_len, (len-front_len)+1);
359                         len -= front_len;
360                         ret=True;
361                 }
362         }
363         
364         if (back_len) {
365                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
366                         s[len-back_len]='\0';
367                         len -= back_len;
368                         ret=True;
369                 }
370         }
371         return ret;
372 }
373
374 /**
375  Does a string have any uppercase chars in it?
376 **/
377
378 BOOL strhasupper(const char *s)
379 {
380         smb_ucs2_t *ptr;
381         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
382         for(ptr=tmpbuf;*ptr;ptr++)
383                 if(isupper_w(*ptr))
384                         return True;
385         return(False);
386 }
387
388 /**
389  Does a string have any lowercase chars in it?
390 **/
391
392 BOOL strhaslower(const char *s)
393 {
394         smb_ucs2_t *ptr;
395         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
396         for(ptr=tmpbuf;*ptr;ptr++)
397                 if(islower_w(*ptr))
398                         return True;
399         return(False);
400 }
401
402 /**
403  Find the number of 'c' chars in a string
404 **/
405
406 size_t count_chars(const char *s,char c)
407 {
408         smb_ucs2_t *ptr;
409         int count;
410         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
411         for(count=0,ptr=tmpbuf;*ptr;ptr++)
412                 if(*ptr==UCS2_CHAR(c))
413                         count++;
414         return(count);
415 }
416
417 /**
418  * In developer builds, clobber a region of memory.
419  *
420  * If we think a string buffer is longer than it really is, this ought
421  * to make the failure obvious, by segfaulting (if in the heap) or by
422  * killing the return address (on the stack), or by trapping under a
423  * memory debugger.
424  *
425  * This is meant to catch possible string overflows, even if the
426  * actual string copied is not big enough to cause an overflow.
427  *
428  * In addition, under Valgrind the buffer is marked as uninitialized.
429  **/
430 void clobber_region(const char *fn, unsigned int line, char *dest, size_t len)
431 {
432 #ifdef DEVELOPER
433         global_clobber_region_function = fn;
434         global_clobber_region_line = line;
435
436         /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */
437         memset(dest, 0xF1, len);
438 #ifdef VALGRIND
439         /* Even though we just wrote to this, from the application's
440          * point of view it is not initialized.
441          *
442          * (This is not redundant with the clobbering above.  The
443          * marking might not actually take effect if we're not running
444          * under valgrind.) */
445         VALGRIND_MAKE_WRITABLE(dest, len);
446 #endif /* VALGRIND */
447 #endif /* DEVELOPER */
448 }
449
450
451 /**
452  Safe string copy into a known length string. maxlength does not
453  include the terminating zero.
454 **/
455
456 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
457 {
458         size_t len;
459
460         if (!dest) {
461                 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
462                 return NULL;
463         }
464
465         clobber_region(fn,line,dest, maxlength+1);
466
467         if (!src) {
468                 *dest = 0;
469                 return dest;
470         }  
471
472         len = strlen(src);
473
474         if (len > maxlength) {
475                 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
476                          (unsigned int)(len-maxlength), len, maxlength, src));
477                 len = maxlength;
478         }
479       
480         memmove(dest, src, len);
481         dest[len] = 0;
482         return dest;
483 }  
484
485 /**
486  Safe string cat into a string. maxlength does not
487  include the terminating zero.
488 **/
489 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
490 {
491         size_t src_len, dest_len;
492
493         if (!dest) {
494                 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
495                 return NULL;
496         }
497
498         if (!src)
499                 return dest;
500         
501         src_len = strlen(src);
502         dest_len = strlen(dest);
503
504         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
505
506         if (src_len + dest_len > maxlength) {
507                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
508                          (int)(src_len + dest_len - maxlength), src));
509                 if (maxlength > dest_len) {
510                         memcpy(&dest[dest_len], src, maxlength - dest_len);
511                 }
512                 dest[maxlength] = 0;
513                 return NULL;
514         }
515
516         memcpy(&dest[dest_len], src, src_len);
517         dest[dest_len + src_len] = 0;
518         return dest;
519 }
520
521 /**
522  Paranoid strcpy into a buffer of given length (includes terminating
523  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
524  and replaces with '_'. Deliberately does *NOT* check for multibyte
525  characters. Don't change it !
526 **/
527 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
528 {
529         size_t len, i;
530
531         clobber_region(fn, line, dest, maxlength);
532
533         if (!dest) {
534                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
535                 return NULL;
536         }
537
538         if (!src) {
539                 *dest = 0;
540                 return dest;
541         }  
542
543         len = strlen(src);
544         if (len >= maxlength)
545                 len = maxlength - 1;
546
547         if (!other_safe_chars)
548                 other_safe_chars = "";
549
550         for(i = 0; i < len; i++) {
551                 int val = (src[i] & 0xff);
552                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
553                         dest[i] = src[i];
554                 else
555                         dest[i] = '_';
556         }
557
558         dest[i] = '\0';
559
560         return dest;
561 }
562
563 /**
564  Like strncpy but always null terminates. Make sure there is room!
565  The variable n should always be one less than the available size.
566 **/
567 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
568 {
569         char *d = dest;
570
571         clobber_region(fn, line, dest, n+1);
572
573         if (!dest)
574                 return(NULL);
575         
576         if (!src) {
577                 *dest = 0;
578                 return(dest);
579         }
580         while (n-- && (*d++ = *src++))
581                 ;
582         *d = 0;
583         return(dest);
584 }
585
586 #if 0
587 /**
588  Like strncpy but copies up to the character marker.  always null terminates.
589  returns a pointer to the character marker in the source string (src).
590 **/
591
592 static char *strncpyn(char *dest, const char *src, size_t n, char c)
593 {
594         char *p;
595         size_t str_len;
596
597         clobber_region(dest, n+1);
598
599         p = strchr_m(src, c);
600         if (p == NULL) {
601                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
602                 return NULL;
603         }
604
605         str_len = PTR_DIFF(p, src);
606         strncpy(dest, src, MIN(n, str_len));
607         dest[str_len] = '\0';
608
609         return p;
610 }
611 #endif
612
613 /**
614  Routine to get hex characters and turn them into a 16 byte array.
615  the array can be variable length, and any non-hex-numeric
616  characters are skipped.  "0xnn" or "0Xnn" is specially catered
617  for.
618
619  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
620
621 **/
622
623 size_t strhex_to_str(char *p, size_t len, const char *strhex)
624 {
625         size_t i;
626         size_t num_chars = 0;
627         unsigned char   lonybble, hinybble;
628         const char     *hexchars = "0123456789ABCDEF";
629         char           *p1 = NULL, *p2 = NULL;
630
631         for (i = 0; i < len && strhex[i] != 0; i++) {
632                 if (strnequal(hexchars, "0x", 2)) {
633                         i++; /* skip two chars */
634                         continue;
635                 }
636
637                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
638                         break;
639
640                 i++; /* next hex digit */
641
642                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
643                         break;
644
645                 /* get the two nybbles */
646                 hinybble = PTR_DIFF(p1, hexchars);
647                 lonybble = PTR_DIFF(p2, hexchars);
648
649                 p[num_chars] = (hinybble << 4) | lonybble;
650                 num_chars++;
651
652                 p1 = NULL;
653                 p2 = NULL;
654         }
655         return num_chars;
656 }
657
658 /**
659  Check if a string is part of a list.
660 **/
661
662 BOOL in_list(char *s,char *list,BOOL casesensitive)
663 {
664         pstring tok;
665         const char *p=list;
666
667         if (!list)
668                 return(False);
669
670         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
671                 if (casesensitive) {
672                         if (strcmp(tok,s) == 0)
673                                 return(True);
674                 } else {
675                         if (StrCaseCmp(tok,s) == 0)
676                                 return(True);
677                 }
678         }
679         return(False);
680 }
681
682 /* this is used to prevent lots of mallocs of size 1 */
683 static char *null_string = NULL;
684
685 /**
686  Set a string value, allocing the space for the string
687 **/
688
689 static BOOL string_init(char **dest,const char *src)
690 {
691         size_t l;
692         if (!src)     
693                 src = "";
694
695         l = strlen(src);
696
697         if (l == 0) {
698                 if (!null_string) {
699                         if((null_string = (char *)malloc(1)) == NULL) {
700                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
701                                 return False;
702                         }
703                         *null_string = 0;
704                 }
705                 *dest = null_string;
706         } else {
707                 (*dest) = strdup(src);
708                 if ((*dest) == NULL) {
709                         DEBUG(0,("Out of memory in string_init\n"));
710                         return False;
711                 }
712         }
713         return(True);
714 }
715
716 /**
717  Free a string value.
718 **/
719
720 void string_free(char **s)
721 {
722         if (!s || !(*s))
723                 return;
724         if (*s == null_string)
725                 *s = NULL;
726         SAFE_FREE(*s);
727 }
728
729 /**
730  Set a string value, deallocating any existing space, and allocing the space
731  for the string
732 **/
733
734 BOOL string_set(char **dest,const char *src)
735 {
736         string_free(dest);
737         return(string_init(dest,src));
738 }
739
740 /**
741  Substitute a string for a pattern in another string. Make sure there is 
742  enough room!
743
744  This routine looks for pattern in s and replaces it with 
745  insert. It may do multiple replacements.
746
747  Any of " ; ' $ or ` in the insert string are replaced with _
748  if len==0 then the string cannot be extended. This is different from the old
749  use of len==0 which was for no length checks to be done.
750 **/
751
752 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
753 {
754         char *p;
755         ssize_t ls,lp,li, i;
756
757         if (!insert || !pattern || !*pattern || !s)
758                 return;
759
760         ls = (ssize_t)strlen(s);
761         lp = (ssize_t)strlen(pattern);
762         li = (ssize_t)strlen(insert);
763
764         if (len == 0)
765                 len = ls + 1; /* len is number of *bytes* */
766
767         while (lp <= ls && (p = strstr(s,pattern))) {
768                 if (ls + (li-lp) >= len) {
769                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
770                                  (int)(ls + (li-lp) - len),
771                                  pattern, (int)len));
772                         break;
773                 }
774                 if (li != lp) {
775                         memmove(p+li,p+lp,strlen(p+lp)+1);
776                 }
777                 for (i=0;i<li;i++) {
778                         switch (insert[i]) {
779                         case '`':
780                         case '"':
781                         case '\'':
782                         case ';':
783                         case '$':
784                         case '%':
785                         case '\r':
786                         case '\n':
787                                 p[i] = '_';
788                                 break;
789                         default:
790                                 p[i] = insert[i];
791                         }
792                 }
793                 s = p + li;
794                 ls += (li-lp);
795         }
796 }
797
798 void fstring_sub(char *s,const char *pattern,const char *insert)
799 {
800         string_sub(s, pattern, insert, sizeof(fstring));
801 }
802
803 void pstring_sub(char *s,const char *pattern,const char *insert)
804 {
805         string_sub(s, pattern, insert, sizeof(pstring));
806 }
807
808 /**
809  Similar to string_sub, but it will accept only allocated strings
810  and may realloc them so pay attention at what you pass on no
811  pointers inside strings, no pstrings or const may be passed
812  as string.
813 **/
814
815 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
816 {
817         char *p, *in;
818         char *s;
819         ssize_t ls,lp,li,ld, i;
820
821         if (!insert || !pattern || !*pattern || !string || !*string)
822                 return NULL;
823
824         s = string;
825
826         in = strdup(insert);
827         if (!in) {
828                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
829                 return NULL;
830         }
831         ls = (ssize_t)strlen(s);
832         lp = (ssize_t)strlen(pattern);
833         li = (ssize_t)strlen(insert);
834         ld = li - lp;
835         for (i=0;i<li;i++) {
836                 switch (in[i]) {
837                         case '`':
838                         case '"':
839                         case '\'':
840                         case ';':
841                         case '$':
842                         case '%':
843                         case '\r':
844                         case '\n':
845                                 in[i] = '_';
846                         default:
847                                 /* ok */
848                                 break;
849                 }
850         }
851         
852         while ((p = strstr(s,pattern))) {
853                 if (ld > 0) {
854                         char *t = Realloc(string, ls + ld + 1);
855                         if (!t) {
856                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
857                                 SAFE_FREE(in);
858                                 return NULL;
859                         }
860                         string = t;
861                         p = t + (p - s);
862                 }
863                 if (li != lp) {
864                         memmove(p+li,p+lp,strlen(p+lp)+1);
865                 }
866                 memcpy(p, in, li);
867                 s = p + li;
868                 ls += ld;
869         }
870         SAFE_FREE(in);
871         return string;
872 }
873
874 /**
875  Similar to string_sub() but allows for any character to be substituted. 
876  Use with caution!
877  if len==0 then the string cannot be extended. This is different from the old
878  use of len==0 which was for no length checks to be done.
879 **/
880
881 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
882 {
883         char *p;
884         ssize_t ls,lp,li;
885
886         if (!insert || !pattern || !s)
887                 return;
888
889         ls = (ssize_t)strlen(s);
890         lp = (ssize_t)strlen(pattern);
891         li = (ssize_t)strlen(insert);
892
893         if (!*pattern)
894                 return;
895         
896         if (len == 0)
897                 len = ls + 1; /* len is number of *bytes* */
898         
899         while (lp <= ls && (p = strstr(s,pattern))) {
900                 if (ls + (li-lp) >= len) {
901                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
902                                  (int)(ls + (li-lp) - len),
903                                  pattern, (int)len));
904                         break;
905                 }
906                 if (li != lp) {
907                         memmove(p+li,p+lp,strlen(p+lp)+1);
908                 }
909                 memcpy(p, insert, li);
910                 s = p + li;
911                 ls += (li-lp);
912         }
913 }
914
915 /**
916  Similar to all_string_sub but for unicode strings.
917  Return a new allocated unicode string.
918  similar to string_sub() but allows for any character to be substituted.
919  Use with caution!
920 **/
921
922 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
923                                 const smb_ucs2_t *insert)
924 {
925         smb_ucs2_t *r, *rp;
926         const smb_ucs2_t *sp;
927         size_t  lr, lp, li, lt;
928
929         if (!insert || !pattern || !*pattern || !s)
930                 return NULL;
931
932         lt = (size_t)strlen_w(s);
933         lp = (size_t)strlen_w(pattern);
934         li = (size_t)strlen_w(insert);
935
936         if (li > lp) {
937                 const smb_ucs2_t *st = s;
938                 int ld = li - lp;
939                 while ((sp = strstr_w(st, pattern))) {
940                         st = sp + lp;
941                         lt += ld;
942                 }
943         }
944
945         r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
946         if (!r) {
947                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
948                 return NULL;
949         }
950
951         while ((sp = strstr_w(s, pattern))) {
952                 memcpy(rp, s, (sp - s));
953                 rp += ((sp - s) / sizeof(smb_ucs2_t));
954                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
955                 s = sp + lp;
956                 rp += li;
957         }
958         lr = ((rp - r) / sizeof(smb_ucs2_t));
959         if (lr < lt) {
960                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
961                 rp += (lt - lr);
962         }
963         *rp = 0;
964
965         return r;
966 }
967
968 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
969                                              const char *insert)
970 {
971         wpstring p, i;
972
973         if (!insert || !pattern || !s)
974                 return NULL;
975         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
976         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
977         return all_string_sub_w(s, p, i);
978 }
979
980 #if 0
981 /**
982  Splits out the front and back at a separator.
983 **/
984
985 static void split_at_last_component(char *path, char *front, char sep, char *back)
986 {
987         char *p = strrchr_m(path, sep);
988
989         if (p != NULL)
990                 *p = 0;
991
992         if (front != NULL)
993                 pstrcpy(front, path);
994
995         if (p != NULL) {
996                 if (back != NULL)
997                         pstrcpy(back, p+1);
998                 *p = '\\';
999         } else {
1000                 if (back != NULL)
1001                         back[0] = 0;
1002         }
1003 }
1004 #endif
1005
1006 /**
1007  Write an octal as a string.
1008 **/
1009
1010 const char *octal_string(int i)
1011 {
1012         static char ret[64];
1013         if (i == -1)
1014                 return "-1";
1015         slprintf(ret, sizeof(ret)-1, "0%o", i);
1016         return ret;
1017 }
1018
1019
1020 /**
1021  Truncate a string at a specified length.
1022 **/
1023
1024 char *string_truncate(char *s, unsigned int length)
1025 {
1026         if (s && strlen(s) > length)
1027                 s[length] = 0;
1028         return s;
1029 }
1030
1031 /**
1032  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1033  We convert via ucs2 for now.
1034 **/
1035
1036 char *strchr_m(const char *s, char c)
1037 {
1038         wpstring ws;
1039         pstring s2;
1040         smb_ucs2_t *p;
1041
1042         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1043         p = strchr_w(ws, UCS2_CHAR(c));
1044         if (!p)
1045                 return NULL;
1046         *p = 0;
1047         pull_ucs2_pstring(s2, ws);
1048         return (char *)(s+strlen(s2));
1049 }
1050
1051 char *strrchr_m(const char *s, char c)
1052 {
1053         wpstring ws;
1054         pstring s2;
1055         smb_ucs2_t *p;
1056
1057         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1058         p = strrchr_w(ws, UCS2_CHAR(c));
1059         if (!p)
1060                 return NULL;
1061         *p = 0;
1062         pull_ucs2_pstring(s2, ws);
1063         return (char *)(s+strlen(s2));
1064 }
1065
1066 /**
1067  Convert a string to lower case.
1068 **/
1069
1070 void strlower_m(char *s)
1071 {
1072         /* this is quite a common operation, so we want it to be
1073            fast. We optimise for the ascii case, knowing that all our
1074            supported multi-byte character sets are ascii-compatible
1075            (ie. they match for the first 128 chars) */
1076
1077         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1078                 *s = tolower((unsigned char)*s);
1079                 s++;
1080         }
1081
1082         if (!*s)
1083                 return;
1084
1085         /* I assume that lowercased string takes the same number of bytes
1086          * as source string even in UTF-8 encoding. (VIV) */
1087         unix_strlower(s,strlen(s)+1,s,strlen(s)+1);     
1088 }
1089
1090 /**
1091  Duplicate convert a string to lower case.
1092 **/
1093
1094 char *strdup_lower(const char *s)
1095 {
1096         char *t = strdup(s);
1097         if (t == NULL) {
1098                 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1099                 return NULL;
1100         }
1101         strlower_m(t);
1102         return t;
1103 }
1104
1105 /**
1106  Convert a string to upper case.
1107 **/
1108
1109 void strupper_m(char *s)
1110 {
1111         /* this is quite a common operation, so we want it to be
1112            fast. We optimise for the ascii case, knowing that all our
1113            supported multi-byte character sets are ascii-compatible
1114            (ie. they match for the first 128 chars) */
1115
1116         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1117                 *s = toupper((unsigned char)*s);
1118                 s++;
1119         }
1120
1121         if (!*s)
1122                 return;
1123
1124         /* I assume that lowercased string takes the same number of bytes
1125          * as source string even in multibyte encoding. (VIV) */
1126         unix_strupper(s,strlen(s)+1,s,strlen(s)+1);     
1127 }
1128
1129 /**
1130  Convert a string to upper case.
1131 **/
1132
1133 char *strdup_upper(const char *s)
1134 {
1135         char *t = strdup(s);
1136         if (t == NULL) {
1137                 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1138                 return NULL;
1139         }
1140         strupper_m(t);
1141         return t;
1142 }
1143
1144 /**
1145  Return a RFC2254 binary string representation of a buffer.
1146  Used in LDAP filters.
1147  Caller must free.
1148 **/
1149
1150 char *binary_string(char *buf, int len)
1151 {
1152         char *s;
1153         int i, j;
1154         const char *hex = "0123456789ABCDEF";
1155         s = malloc(len * 3 + 1);
1156         if (!s)
1157                 return NULL;
1158         for (j=i=0;i<len;i++) {
1159                 s[j] = '\\';
1160                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1161                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1162                 j += 3;
1163         }
1164         s[j] = 0;
1165         return s;
1166 }
1167
1168 /**
1169  Just a typesafety wrapper for snprintf into a pstring.
1170 **/
1171
1172  int pstr_sprintf(pstring s, const char *fmt, ...)
1173 {
1174         va_list ap;
1175         int ret;
1176
1177         va_start(ap, fmt);
1178         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1179         va_end(ap);
1180         return ret;
1181 }
1182
1183 #if 0
1184 /**
1185  Just a typesafety wrapper for snprintf into a fstring.
1186 **/
1187
1188 static int fstr_sprintf(fstring s, const char *fmt, ...)
1189 {
1190         va_list ap;
1191         int ret;
1192
1193         va_start(ap, fmt);
1194         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1195         va_end(ap);
1196         return ret;
1197 }
1198 #endif
1199
1200 #ifndef HAVE_STRNDUP
1201 /**
1202  Some platforms don't have strndup.
1203 **/
1204
1205  char *strndup(const char *s, size_t n)
1206 {
1207         char *ret;
1208         
1209         n = strnlen(s, n);
1210         ret = malloc(n+1);
1211         if (!ret)
1212                 return NULL;
1213         memcpy(ret, s, n);
1214         ret[n] = 0;
1215
1216         return ret;
1217 }
1218 #endif
1219
1220 #ifndef HAVE_STRNLEN
1221 /**
1222  Some platforms don't have strnlen
1223 **/
1224
1225  size_t strnlen(const char *s, size_t n)
1226 {
1227         int i;
1228         for (i=0; s[i] && i<n; i++)
1229                 /* noop */ ;
1230         return i;
1231 }
1232 #endif
1233
1234 /**
1235  List of Strings manipulation functions
1236 **/
1237
1238 #define S_LIST_ABS 16 /* List Allocation Block Size */
1239
1240 char **str_list_make(const char *string, const char *sep)
1241 {
1242         char **list, **rlist;
1243         const char *str;
1244         char *s;
1245         int num, lsize;
1246         pstring tok;
1247         
1248         if (!string || !*string)
1249                 return NULL;
1250         s = strdup(string);
1251         if (!s) {
1252                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1253                 return NULL;
1254         }
1255         if (!sep) sep = LIST_SEP;
1256         
1257         num = lsize = 0;
1258         list = NULL;
1259         
1260         str = s;
1261         while (next_token(&str, tok, sep, sizeof(tok))) {               
1262                 if (num == lsize) {
1263                         lsize += S_LIST_ABS;
1264                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1265                         if (!rlist) {
1266                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1267                                 str_list_free(&list);
1268                                 SAFE_FREE(s);
1269                                 return NULL;
1270                         } else
1271                                 list = rlist;
1272                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1273                 }
1274                 
1275                 list[num] = strdup(tok);
1276                 if (!list[num]) {
1277                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1278                         str_list_free(&list);
1279                         SAFE_FREE(s);
1280                         return NULL;
1281                 }
1282         
1283                 num++;  
1284         }
1285         
1286         SAFE_FREE(s);
1287         return list;
1288 }
1289
1290 BOOL str_list_copy(char ***dest, const char **src)
1291 {
1292         char **list, **rlist;
1293         int num, lsize;
1294         
1295         *dest = NULL;
1296         if (!src)
1297                 return False;
1298         
1299         num = lsize = 0;
1300         list = NULL;
1301                 
1302         while (src[num]) {
1303                 if (num == lsize) {
1304                         lsize += S_LIST_ABS;
1305                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1306                         if (!rlist) {
1307                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1308                                 str_list_free(&list);
1309                                 return False;
1310                         } else
1311                                 list = rlist;
1312                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1313                 }
1314                 
1315                 list[num] = strdup(src[num]);
1316                 if (!list[num]) {
1317                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1318                         str_list_free(&list);
1319                         return False;
1320                 }
1321
1322                 num++;
1323         }
1324         
1325         *dest = list;
1326         return True;    
1327 }
1328
1329 /**
1330  * Return true if all the elements of the list match exactly.
1331  **/
1332 BOOL str_list_compare(char **list1, char **list2)
1333 {
1334         int num;
1335         
1336         if (!list1 || !list2)
1337                 return (list1 == list2); 
1338         
1339         for (num = 0; list1[num]; num++) {
1340                 if (!list2[num])
1341                         return False;
1342                 if (!strcsequal(list1[num], list2[num]))
1343                         return False;
1344         }
1345         if (list2[num])
1346                 return False; /* if list2 has more elements than list1 fail */
1347         
1348         return True;
1349 }
1350
1351 void str_list_free(char ***list)
1352 {
1353         char **tlist;
1354         
1355         if (!list || !*list)
1356                 return;
1357         tlist = *list;
1358         for(; *tlist; tlist++)
1359                 SAFE_FREE(*tlist);
1360         SAFE_FREE(*list);
1361 }
1362
1363 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1364 {
1365         char *p, *s, *t;
1366         ssize_t ls, lp, li, ld, i, d;
1367
1368         if (!list)
1369                 return False;
1370         if (!pattern)
1371                 return False;
1372         if (!insert)
1373                 return False;
1374
1375         lp = (ssize_t)strlen(pattern);
1376         li = (ssize_t)strlen(insert);
1377         ld = li -lp;
1378                         
1379         while (*list) {
1380                 s = *list;
1381                 ls = (ssize_t)strlen(s);
1382
1383                 while ((p = strstr(s, pattern))) {
1384                         t = *list;
1385                         d = p -t;
1386                         if (ld) {
1387                                 t = (char *) malloc(ls +ld +1);
1388                                 if (!t) {
1389                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1390                                         return False;
1391                                 }
1392                                 memcpy(t, *list, d);
1393                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1394                                 SAFE_FREE(*list);
1395                                 *list = t;
1396                                 ls += ld;
1397                                 s = t +d +li;
1398                         }
1399                         
1400                         for (i = 0; i < li; i++) {
1401                                 switch (insert[i]) {
1402                                         case '`':
1403                                         case '"':
1404                                         case '\'':
1405                                         case ';':
1406                                         case '$':
1407                                         case '%':
1408                                         case '\r':
1409                                         case '\n':
1410                                                 t[d +i] = '_';
1411                                                 break;
1412                                         default:
1413                                                 t[d +i] = insert[i];
1414                                 }
1415                         }       
1416                 }
1417                 
1418                 list++;
1419         }
1420         
1421         return True;
1422 }
1423
1424
1425 #define IPSTR_LIST_SEP  ","
1426
1427 /**
1428  * Add ip string representation to ipstr list. Used also
1429  * as part of @function ipstr_list_make
1430  *
1431  * @param ipstr_list pointer to string containing ip list;
1432  *        MUST BE already allocated and IS reallocated if necessary
1433  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1434  *        as a result of reallocation)
1435  * @param ip IP address which is to be added to list
1436  * @return pointer to string appended with new ip and possibly
1437  *         reallocated to new length
1438  **/
1439
1440 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1441 {
1442         char* new_ipstr = NULL;
1443         
1444         /* arguments checking */
1445         if (!ipstr_list || !ip) return NULL;
1446
1447         /* attempt to convert ip to a string and append colon separator to it */
1448         if (*ipstr_list) {
1449                 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1450                 SAFE_FREE(*ipstr_list);
1451         } else {
1452                 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1453         }
1454         *ipstr_list = new_ipstr;
1455         return *ipstr_list;
1456 }
1457
1458
1459 /**
1460  * Allocate and initialise an ipstr list using ip adresses
1461  * passed as arguments.
1462  *
1463  * @param ipstr_list pointer to string meant to be allocated and set
1464  * @param ip_list array of ip addresses to place in the list
1465  * @param ip_count number of addresses stored in ip_list
1466  * @return pointer to allocated ip string
1467  **/
1468  
1469 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1470 {
1471         int i;
1472         
1473         /* arguments checking */
1474         if (!ip_list && !ipstr_list) return 0;
1475
1476         *ipstr_list = NULL;
1477         
1478         /* process ip addresses given as arguments */
1479         for (i = 0; i < ip_count; i++)
1480                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1481         
1482         return (*ipstr_list);
1483 }
1484
1485
1486 /**
1487  * Parse given ip string list into array of ip addresses
1488  * (as in_addr structures)
1489  *
1490  * @param ipstr ip string list to be parsed 
1491  * @param ip_list pointer to array of ip addresses which is
1492  *        allocated by this function and must be freed by caller
1493  * @return number of succesfully parsed addresses
1494  **/
1495  
1496 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1497 {
1498         fstring token_str;
1499         int count;
1500
1501         if (!ipstr_list || !ip_list) return 0;
1502         
1503         for (*ip_list = NULL, count = 0;
1504              next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1505              count++) {
1506              
1507                 struct in_addr addr;
1508
1509                 /* convert single token to ip address */
1510                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1511                         break;
1512                 
1513                 /* prepare place for another in_addr structure */
1514                 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1515                 if (!*ip_list) return -1;
1516                 
1517                 (*ip_list)[count] = addr;
1518         }
1519         
1520         return count;
1521 }
1522
1523
1524 /**
1525  * Safely free ip string list
1526  *
1527  * @param ipstr_list ip string list to be freed
1528  **/
1529
1530 void ipstr_list_free(char* ipstr_list)
1531 {
1532         SAFE_FREE(ipstr_list);
1533 }
1534
1535
1536 /**
1537  Unescape a URL encoded string, in place.
1538 **/
1539
1540 void rfc1738_unescape(char *buf)
1541 {
1542         char *p=buf;
1543
1544         while ((p=strchr_m(p,'+')))
1545                 *p = ' ';
1546
1547         p = buf;
1548
1549         while (p && *p && (p=strchr_m(p,'%'))) {
1550                 int c1 = p[1];
1551                 int c2 = p[2];
1552
1553                 if (c1 >= '0' && c1 <= '9')
1554                         c1 = c1 - '0';
1555                 else if (c1 >= 'A' && c1 <= 'F')
1556                         c1 = 10 + c1 - 'A';
1557                 else if (c1 >= 'a' && c1 <= 'f')
1558                         c1 = 10 + c1 - 'a';
1559                 else {p++; continue;}
1560
1561                 if (c2 >= '0' && c2 <= '9')
1562                         c2 = c2 - '0';
1563                 else if (c2 >= 'A' && c2 <= 'F')
1564                         c2 = 10 + c2 - 'A';
1565                 else if (c2 >= 'a' && c2 <= 'f')
1566                         c2 = 10 + c2 - 'a';
1567                 else {p++; continue;}
1568                         
1569                 *p = (c1<<4) | c2;
1570
1571                 memmove(p+1, p+3, strlen(p+3)+1);
1572                 p++;
1573         }
1574 }
1575
1576 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1577
1578 /**
1579  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1580  **/
1581 DATA_BLOB base64_decode_data_blob(const char *s)
1582 {
1583         int bit_offset, byte_offset, idx, i, n;
1584         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1585         unsigned char *d = decoded.data;
1586         char *p;
1587
1588         n=i=0;
1589
1590         while (*s && (p=strchr_m(b64,*s))) {
1591                 idx = (int)(p - b64);
1592                 byte_offset = (i*6)/8;
1593                 bit_offset = (i*6)%8;
1594                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1595                 if (bit_offset < 3) {
1596                         d[byte_offset] |= (idx << (2-bit_offset));
1597                         n = byte_offset+1;
1598                 } else {
1599                         d[byte_offset] |= (idx >> (bit_offset-2));
1600                         d[byte_offset+1] = 0;
1601                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1602                         n = byte_offset+2;
1603                 }
1604                 s++; i++;
1605         }
1606
1607         /* fix up length */
1608         decoded.length = n;
1609         return decoded;
1610 }
1611
1612 /**
1613  * Decode a base64 string in-place - wrapper for the above
1614  **/
1615 void base64_decode_inplace(char *s)
1616 {
1617         DATA_BLOB decoded = base64_decode_data_blob(s);
1618         memcpy(s, decoded.data, decoded.length);
1619         data_blob_free(&decoded);
1620
1621         /* null terminate */
1622         s[decoded.length] = '\0';
1623 }
1624
1625 /**
1626  * Encode a base64 string into a malloc()ed string caller to free.
1627  *
1628  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1629  **/
1630 char * base64_encode_data_blob(DATA_BLOB data)
1631 {
1632         int bits = 0;
1633         int char_count = 0;
1634         size_t out_cnt = 0;
1635         size_t len = data.length;
1636         size_t output_len = data.length * 2;
1637         char *result = malloc(output_len); /* get us plenty of space */
1638
1639         while (len-- && out_cnt < (data.length * 2) - 5) {
1640                 int c = (unsigned char) *(data.data++);
1641                 bits += c;
1642                 char_count++;
1643                 if (char_count == 3) {
1644                         result[out_cnt++] = b64[bits >> 18];
1645                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1646                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1647             result[out_cnt++] = b64[bits & 0x3f];
1648             bits = 0;
1649             char_count = 0;
1650         } else {
1651             bits <<= 8;
1652         }
1653     }
1654     if (char_count != 0) {
1655         bits <<= 16 - (8 * char_count);
1656         result[out_cnt++] = b64[bits >> 18];
1657         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1658         if (char_count == 1) {
1659             result[out_cnt++] = '=';
1660             result[out_cnt++] = '=';
1661         } else {
1662             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1663             result[out_cnt++] = '=';
1664         }
1665     }
1666     result[out_cnt] = '\0';     /* terminate */
1667     return result;
1668 }
1669