Clobber strings with 0xf1f1f1f1 before writing to them to check buffer
[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 /**
25  * Get the next token from a string, return False if none found.
26  * Handles double-quotes.
27  * 
28  * Based on a routine by GJC@VILLAGE.COM. 
29  * Extensively modified by Andrew.Tridgell@anu.edu.au
30  **/
31 BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
32 {
33         const char *s;
34         BOOL quoted;
35         size_t len=1;
36
37         if (!ptr)
38                 return(False);
39
40         s = *ptr;
41
42         /* default to simple separators */
43         if (!sep)
44                 sep = " \t\n\r";
45
46         /* find the first non sep char */
47         while (*s && strchr_m(sep,*s))
48                 s++;
49         
50         /* nothing left? */
51         if (! *s)
52                 return(False);
53         
54         /* copy over the token */
55         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
56                 if (*s == '\"') {
57                         quoted = !quoted;
58                 } else {
59                         len++;
60                         *buff++ = *s;
61                 }
62         }
63         
64         *ptr = (*s) ? s+1 : s;  
65         *buff = 0;
66         
67         return(True);
68 }
69
70 /**
71 This is like next_token but is not re-entrant and "remembers" the first 
72 parameter so you can pass NULL. This is useful for user interface code
73 but beware the fact that it is not re-entrant!
74 **/
75
76 static char *last_ptr=NULL;
77
78 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
79 {
80         BOOL ret;
81         if (!ptr)
82                 ptr = (const char **)&last_ptr;
83
84         ret = next_token(ptr, buff, sep, bufsize);
85         last_ptr = *ptr;
86         return ret;     
87 }
88
89 static uint16 tmpbuf[sizeof(pstring)];
90
91 void set_first_token(char *ptr)
92 {
93         last_ptr = ptr;
94 }
95
96 /**
97  Convert list of tokens to array; dependent on above routine.
98  Uses last_ptr from above - bit of a hack.
99 **/
100
101 char **toktocliplist(int *ctok, const char *sep)
102 {
103         char *s=last_ptr;
104         int ictok=0;
105         char **ret, **iret;
106
107         if (!sep)
108                 sep = " \t\n\r";
109
110         while(*s && strchr_m(sep,*s))
111                 s++;
112
113         /* nothing left? */
114         if (!*s)
115                 return(NULL);
116
117         do {
118                 ictok++;
119                 while(*s && (!strchr_m(sep,*s)))
120                         s++;
121                 while(*s && strchr_m(sep,*s))
122                         *s++=0;
123         } while(*s);
124         
125         *ctok=ictok;
126         s=last_ptr;
127         
128         if (!(ret=iret=malloc(ictok*sizeof(char *))))
129                 return NULL;
130         
131         while(ictok--) {    
132                 *iret++=s;
133                 while(*s++)
134                         ;
135                 while(!*s)
136                         s++;
137         }
138
139         return ret;
140 }
141
142 /**
143  Case insensitive string compararison.
144 **/
145
146 int StrCaseCmp(const char *s, const char *t)
147 {
148         pstring buf1, buf2;
149         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
150         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
151         return strcmp(buf1,buf2);
152 }
153
154 /**
155  Case insensitive string compararison, length limited.
156 **/
157
158 int StrnCaseCmp(const char *s, const char *t, size_t n)
159 {
160         pstring buf1, buf2;
161         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
162         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
163         return strncmp(buf1,buf2,n);
164 }
165
166 /**
167  * Compare 2 strings.
168  *
169  * @note The comparison is case-insensitive.
170  **/
171 BOOL strequal(const char *s1, const char *s2)
172 {
173         if (s1 == s2)
174                 return(True);
175         if (!s1 || !s2)
176                 return(False);
177   
178         return(StrCaseCmp(s1,s2)==0);
179 }
180
181 /**
182  * Compare 2 strings up to and including the nth char.
183  *
184  * @note The comparison is case-insensitive.
185  **/
186 BOOL strnequal(const char *s1,const char *s2,size_t n)
187 {
188   if (s1 == s2)
189           return(True);
190   if (!s1 || !s2 || !n)
191           return(False);
192   
193   return(StrnCaseCmp(s1,s2,n)==0);
194 }
195
196 /**
197  Compare 2 strings (case sensitive).
198 **/
199
200 BOOL strcsequal(const char *s1,const char *s2)
201 {
202   if (s1 == s2)
203           return(True);
204   if (!s1 || !s2)
205           return(False);
206   
207   return(strcmp(s1,s2)==0);
208 }
209
210 /**
211 Do a case-insensitive, whitespace-ignoring string compare.
212 **/
213
214 int strwicmp(const char *psz1, const char *psz2)
215 {
216         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
217         /* appropriate value. */
218         if (psz1 == psz2)
219                 return (0);
220         else if (psz1 == NULL)
221                 return (-1);
222         else if (psz2 == NULL)
223                 return (1);
224
225         /* sync the strings on first non-whitespace */
226         while (1) {
227                 while (isspace((int)*psz1))
228                         psz1++;
229                 while (isspace((int)*psz2))
230                         psz2++;
231                 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
232                     || *psz2 == '\0')
233                         break;
234                 psz1++;
235                 psz2++;
236         }
237         return (*psz1 - *psz2);
238 }
239
240
241 /**
242  Convert a string to upper case, but don't modify it.
243 **/
244
245 char *strupper_static(const char *s)
246 {
247         static pstring str;
248
249         pstrcpy(str, s);
250         strupper(str);
251
252         return str;
253 }
254
255 /**
256  Convert a string to "normal" form.
257 **/
258
259 void strnorm(char *s)
260 {
261         extern int case_default;
262         if (case_default == CASE_UPPER)
263                 strupper(s);
264         else
265                 strlower(s);
266 }
267
268 /**
269  Check if a string is in "normal" case.
270 **/
271
272 BOOL strisnormal(const char *s)
273 {
274         extern int case_default;
275         if (case_default == CASE_UPPER)
276                 return(!strhaslower(s));
277         
278         return(!strhasupper(s));
279 }
280
281
282 /**
283  String replace.
284  NOTE: oldc and newc must be 7 bit characters
285 **/
286
287 void string_replace(char *s,char oldc,char newc)
288 {
289         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
290         string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
291         pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
292 }
293
294 /**
295  Skip past some strings in a buffer.
296 **/
297
298 char *skip_string(char *buf,size_t n)
299 {
300         while (n--)
301                 buf += strlen(buf) + 1;
302         return(buf);
303 }
304
305 /**
306  Count the number of characters in a string. Normally this will
307  be the same as the number of bytes in a string for single byte strings,
308  but will be different for multibyte.
309 **/
310
311 size_t str_charnum(const char *s)
312 {
313         uint16 tmpbuf2[sizeof(pstring)];
314         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
315         return strlen_w(tmpbuf2);
316 }
317
318 /**
319  Count the number of characters in a string. Normally this will
320  be the same as the number of bytes in a string for single byte strings,
321  but will be different for multibyte.
322 **/
323
324 size_t str_ascii_charnum(const char *s)
325 {
326         pstring tmpbuf2;
327         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
328         return strlen(tmpbuf2);
329 }
330
331 /**
332  Trim the specified elements off the front and back of a string.
333 **/
334
335 BOOL trim_string(char *s,const char *front,const char *back)
336 {
337         BOOL ret = False;
338         size_t front_len;
339         size_t back_len;
340         size_t len;
341
342         /* Ignore null or empty strings. */
343         if (!s || (s[0] == '\0'))
344                 return False;
345
346         front_len       = front? strlen(front) : 0;
347         back_len        = back? strlen(back) : 0;
348
349         len = strlen(s);
350
351         if (front_len) {
352                 while (len && strncmp(s, front, front_len)==0) {
353                         memcpy(s, s+front_len, (len-front_len)+1);
354                         len -= front_len;
355                         ret=True;
356                 }
357         }
358         
359         if (back_len) {
360                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
361                         s[len-back_len]='\0';
362                         len -= back_len;
363                         ret=True;
364                 }
365         }
366         return ret;
367 }
368
369 /**
370  Does a string have any uppercase chars in it?
371 **/
372
373 BOOL strhasupper(const char *s)
374 {
375         smb_ucs2_t *ptr;
376         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
377         for(ptr=tmpbuf;*ptr;ptr++)
378                 if(isupper_w(*ptr))
379                         return True;
380         return(False);
381 }
382
383 /**
384  Does a string have any lowercase chars in it?
385 **/
386
387 BOOL strhaslower(const char *s)
388 {
389         smb_ucs2_t *ptr;
390         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
391         for(ptr=tmpbuf;*ptr;ptr++)
392                 if(islower_w(*ptr))
393                         return True;
394         return(False);
395 }
396
397 /**
398  Find the number of 'c' chars in a string
399 **/
400
401 size_t count_chars(const char *s,char c)
402 {
403         smb_ucs2_t *ptr;
404         int count;
405         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
406         for(count=0,ptr=tmpbuf;*ptr;ptr++)
407                 if(*ptr==UCS2_CHAR(c))
408                         count++;
409         return(count);
410 }
411
412 /**
413 Return True if a string consists only of one particular character.
414 **/
415
416 BOOL str_is_all(const char *s,char c)
417 {
418         smb_ucs2_t *ptr;
419
420         if(s == NULL)
421                 return False;
422         if(!*s)
423                 return False;
424   
425         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
426         for(ptr=tmpbuf;*ptr;ptr++)
427                 if(*ptr!=UCS2_CHAR(c))
428                         return False;
429
430         return True;
431 }
432
433
434 /**
435  * In developer builds, clobber a region of memory.
436  *
437  * If we think a string buffer is longer than it really is, this ought
438  * to make the failure obvious, by segfaulting (if in the heap) or by
439  * killing the return address (on the stack), or by trapping under a
440  * memory debugger.
441  *
442  * This is meant to catch possible string overflows, even if the
443  * actual string copied is not big enough to cause an overflow.
444  **/
445 void clobber_region(char *dest, size_t len)
446 {
447 #ifdef DEVELOPER
448         /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */
449         memset(dest, 0xF1, len);
450 #endif
451 }
452
453
454 /**
455  Safe string copy into a known length string. maxlength does not
456  include the terminating zero.
457 **/
458
459 char *safe_strcpy(char *dest,const char *src, size_t maxlength)
460 {
461         size_t len;
462
463         if (!dest) {
464                 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
465                 return NULL;
466         }
467
468         clobber_region(dest, maxlength+1);
469
470         if (!src) {
471                 *dest = 0;
472                 return dest;
473         }  
474
475         len = strlen(src);
476
477         if (len > maxlength) {
478                 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
479                          (unsigned int)(len-maxlength), len, maxlength, src));
480                 len = maxlength;
481         }
482       
483         memmove(dest, src, len);
484         dest[len] = 0;
485         return dest;
486 }  
487
488 /**
489  Safe string cat into a string. maxlength does not
490  include the terminating zero.
491 **/
492
493 char *safe_strcat(char *dest, const char *src, size_t maxlength)
494 {
495         size_t src_len, dest_len;
496
497         if (!dest) {
498                 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
499                 return NULL;
500         }
501
502         if (!src)
503                 return dest;
504         
505         src_len = strlen(src);
506         dest_len = strlen(dest);
507
508         clobber_region(dest + dest_len, maxlength + 1 - dest_len);
509         
510         if (src_len + dest_len > maxlength) {
511                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
512                          (int)(src_len + dest_len - maxlength), src));
513                 if (maxlength > dest_len) {
514                         memcpy(&dest[dest_len], src, maxlength - dest_len);
515                 }
516                 dest[maxlength] = 0;
517                 return NULL;
518         }
519
520         memcpy(&dest[dest_len], src, src_len);
521         dest[dest_len + src_len] = 0;
522         return dest;
523 }
524
525 /**
526  Paranoid strcpy into a buffer of given length (includes terminating
527  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
528  and replaces with '_'. Deliberately does *NOT* check for multibyte
529  characters. Don't change it !
530 **/
531
532 char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
533 {
534         size_t len, i;
535
536         clobber_region(dest, maxlength);
537
538         if (!dest) {
539                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
540                 return NULL;
541         }
542
543         if (!src) {
544                 *dest = 0;
545                 return dest;
546         }  
547
548         len = strlen(src);
549         if (len >= maxlength)
550                 len = maxlength - 1;
551
552         if (!other_safe_chars)
553                 other_safe_chars = "";
554
555         for(i = 0; i < len; i++) {
556                 int val = (src[i] & 0xff);
557                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
558                         dest[i] = src[i];
559                 else
560                         dest[i] = '_';
561         }
562
563         dest[i] = '\0';
564
565         return dest;
566 }
567
568 /**
569  Like strncpy but always null terminates. Make sure there is room!
570  The variable n should always be one less than the available size.
571 **/
572
573 char *StrnCpy(char *dest,const char *src,size_t n)
574 {
575         char *d = dest;
576
577         clobber_region(dest, n+1);
578         
579         if (!dest)
580                 return(NULL);
581         
582         if (!src) {
583                 *dest = 0;
584                 return(dest);
585         }
586         while (n-- && (*d++ = *src++))
587                 ;
588         *d = 0;
589         return(dest);
590 }
591
592 /**
593  Like strncpy but copies up to the character marker.  always null terminates.
594  returns a pointer to the character marker in the source string (src).
595 **/
596
597 char *strncpyn(char *dest, const char *src, size_t n, char c)
598 {
599         char *p;
600         size_t str_len;
601
602         clobber_region(dest, n+1);
603
604         p = strchr_m(src, c);
605         if (p == NULL) {
606                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
607                 return NULL;
608         }
609
610         str_len = PTR_DIFF(p, src);
611         strncpy(dest, src, MIN(n, str_len));
612         dest[str_len] = '\0';
613
614         return p;
615 }
616
617 /**
618  Routine to get hex characters and turn them into a 16 byte array.
619  the array can be variable length, and any non-hex-numeric
620  characters are skipped.  "0xnn" or "0Xnn" is specially catered
621  for.
622
623  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
624
625 **/
626
627 size_t strhex_to_str(char *p, size_t len, const char *strhex)
628 {
629         size_t i;
630         size_t num_chars = 0;
631         unsigned char   lonybble, hinybble;
632         const char     *hexchars = "0123456789ABCDEF";
633         char           *p1 = NULL, *p2 = NULL;
634
635         for (i = 0; i < len && strhex[i] != 0; i++) {
636                 if (strnequal(hexchars, "0x", 2)) {
637                         i++; /* skip two chars */
638                         continue;
639                 }
640
641                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
642                         break;
643
644                 i++; /* next hex digit */
645
646                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
647                         break;
648
649                 /* get the two nybbles */
650                 hinybble = PTR_DIFF(p1, hexchars);
651                 lonybble = PTR_DIFF(p2, hexchars);
652
653                 p[num_chars] = (hinybble << 4) | lonybble;
654                 num_chars++;
655
656                 p1 = NULL;
657                 p2 = NULL;
658         }
659         return num_chars;
660 }
661
662 /**
663  Check if a string is part of a list.
664 **/
665
666 BOOL in_list(char *s,char *list,BOOL casesensitive)
667 {
668         pstring tok;
669         const char *p=list;
670
671         if (!list)
672                 return(False);
673
674         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
675                 if (casesensitive) {
676                         if (strcmp(tok,s) == 0)
677                                 return(True);
678                 } else {
679                         if (StrCaseCmp(tok,s) == 0)
680                                 return(True);
681                 }
682         }
683         return(False);
684 }
685
686 /* this is used to prevent lots of mallocs of size 1 */
687 static char *null_string = NULL;
688
689 /**
690  Set a string value, allocing the space for the string
691 **/
692
693 static BOOL string_init(char **dest,const char *src)
694 {
695         size_t l;
696         if (!src)     
697                 src = "";
698
699         l = strlen(src);
700
701         if (l == 0) {
702                 if (!null_string) {
703                         if((null_string = (char *)malloc(1)) == NULL) {
704                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
705                                 return False;
706                         }
707                         *null_string = 0;
708                 }
709                 *dest = null_string;
710         } else {
711                 (*dest) = strdup(src);
712                 if ((*dest) == NULL) {
713                         DEBUG(0,("Out of memory in string_init\n"));
714                         return False;
715                 }
716         }
717         return(True);
718 }
719
720 /**
721  Free a string value.
722 **/
723
724 void string_free(char **s)
725 {
726         if (!s || !(*s))
727                 return;
728         if (*s == null_string)
729                 *s = NULL;
730         SAFE_FREE(*s);
731 }
732
733 /**
734  Set a string value, deallocating any existing space, and allocing the space
735  for the string
736 **/
737
738 BOOL string_set(char **dest,const char *src)
739 {
740         string_free(dest);
741         return(string_init(dest,src));
742 }
743
744 /**
745  Substitute a string for a pattern in another string. Make sure there is 
746  enough room!
747
748  This routine looks for pattern in s and replaces it with 
749  insert. It may do multiple replacements.
750
751  Any of " ; ' $ or ` in the insert string are replaced with _
752  if len==0 then the string cannot be extended. This is different from the old
753  use of len==0 which was for no length checks to be done.
754 **/
755
756 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
757 {
758         char *p;
759         ssize_t ls,lp,li, i;
760
761         if (!insert || !pattern || !*pattern || !s)
762                 return;
763
764         ls = (ssize_t)strlen(s);
765         lp = (ssize_t)strlen(pattern);
766         li = (ssize_t)strlen(insert);
767
768         if (len == 0)
769                 len = ls + 1; /* len is number of *bytes* */
770
771         while (lp <= ls && (p = strstr(s,pattern))) {
772                 if (ls + (li-lp) >= len) {
773                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
774                                  (int)(ls + (li-lp) - len),
775                                  pattern, (int)len));
776                         break;
777                 }
778                 if (li != lp) {
779                         memmove(p+li,p+lp,strlen(p+lp)+1);
780                 }
781                 for (i=0;i<li;i++) {
782                         switch (insert[i]) {
783                         case '`':
784                         case '"':
785                         case '\'':
786                         case ';':
787                         case '$':
788                         case '%':
789                         case '\r':
790                         case '\n':
791                                 p[i] = '_';
792                                 break;
793                         default:
794                                 p[i] = insert[i];
795                         }
796                 }
797                 s = p + li;
798                 ls += (li-lp);
799         }
800 }
801
802 void fstring_sub(char *s,const char *pattern,const char *insert)
803 {
804         string_sub(s, pattern, insert, sizeof(fstring));
805 }
806
807 void pstring_sub(char *s,const char *pattern,const char *insert)
808 {
809         string_sub(s, pattern, insert, sizeof(pstring));
810 }
811
812 /**
813  Similar to string_sub, but it will accept only allocated strings
814  and may realloc them so pay attention at what you pass on no
815  pointers inside strings, no pstrings or const may be passed
816  as string.
817 **/
818
819 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
820 {
821         char *p, *in;
822         char *s;
823         ssize_t ls,lp,li,ld, i;
824
825         if (!insert || !pattern || !*pattern || !string || !*string)
826                 return NULL;
827
828         s = string;
829
830         in = strdup(insert);
831         if (!in) {
832                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
833                 return NULL;
834         }
835         ls = (ssize_t)strlen(s);
836         lp = (ssize_t)strlen(pattern);
837         li = (ssize_t)strlen(insert);
838         ld = li - lp;
839         for (i=0;i<li;i++) {
840                 switch (in[i]) {
841                         case '`':
842                         case '"':
843                         case '\'':
844                         case ';':
845                         case '$':
846                         case '%':
847                         case '\r':
848                         case '\n':
849                                 in[i] = '_';
850                         default:
851                                 /* ok */
852                                 break;
853                 }
854         }
855         
856         while ((p = strstr(s,pattern))) {
857                 if (ld > 0) {
858                         char *t = Realloc(string, ls + ld + 1);
859                         if (!t) {
860                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
861                                 SAFE_FREE(in);
862                                 return NULL;
863                         }
864                         string = t;
865                         p = t + (p - s);
866                 }
867                 if (li != lp) {
868                         memmove(p+li,p+lp,strlen(p+lp)+1);
869                 }
870                 memcpy(p, in, li);
871                 s = p + li;
872                 ls += ld;
873         }
874         SAFE_FREE(in);
875         return string;
876 }
877
878 /**
879  Similar to string_sub() but allows for any character to be substituted. 
880  Use with caution!
881  if len==0 then the string cannot be extended. This is different from the old
882  use of len==0 which was for no length checks to be done.
883 **/
884
885 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
886 {
887         char *p;
888         ssize_t ls,lp,li;
889
890         if (!insert || !pattern || !s)
891                 return;
892
893         ls = (ssize_t)strlen(s);
894         lp = (ssize_t)strlen(pattern);
895         li = (ssize_t)strlen(insert);
896
897         if (!*pattern)
898                 return;
899         
900         if (len == 0)
901                 len = ls + 1; /* len is number of *bytes* */
902         
903         while (lp <= ls && (p = strstr(s,pattern))) {
904                 if (ls + (li-lp) >= len) {
905                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
906                                  (int)(ls + (li-lp) - len),
907                                  pattern, (int)len));
908                         break;
909                 }
910                 if (li != lp) {
911                         memmove(p+li,p+lp,strlen(p+lp)+1);
912                 }
913                 memcpy(p, insert, li);
914                 s = p + li;
915                 ls += (li-lp);
916         }
917 }
918
919 /**
920  Similar to all_string_sub but for unicode strings.
921  Return a new allocated unicode string.
922  similar to string_sub() but allows for any character to be substituted.
923  Use with caution!
924 **/
925
926 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
927                                 const smb_ucs2_t *insert)
928 {
929         smb_ucs2_t *r, *rp;
930         const smb_ucs2_t *sp;
931         size_t  lr, lp, li, lt;
932
933         if (!insert || !pattern || !*pattern || !s)
934                 return NULL;
935
936         lt = (size_t)strlen_w(s);
937         lp = (size_t)strlen_w(pattern);
938         li = (size_t)strlen_w(insert);
939
940         if (li > lp) {
941                 const smb_ucs2_t *st = s;
942                 int ld = li - lp;
943                 while ((sp = strstr_w(st, pattern))) {
944                         st = sp + lp;
945                         lt += ld;
946                 }
947         }
948
949         r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
950         if (!r) {
951                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
952                 return NULL;
953         }
954
955         while ((sp = strstr_w(s, pattern))) {
956                 memcpy(rp, s, (sp - s));
957                 rp += ((sp - s) / sizeof(smb_ucs2_t));
958                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
959                 s = sp + lp;
960                 rp += li;
961         }
962         lr = ((rp - r) / sizeof(smb_ucs2_t));
963         if (lr < lt) {
964                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
965                 rp += (lt - lr);
966         }
967         *rp = 0;
968
969         return r;
970 }
971
972 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
973                                              const char *insert)
974 {
975         wpstring p, i;
976
977         if (!insert || !pattern || !s)
978                 return NULL;
979         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
980         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
981         return all_string_sub_w(s, p, i);
982 }
983
984 /**
985  Splits out the front and back at a separator.
986 **/
987
988 void split_at_last_component(char *path, char *front, char sep, char *back)
989 {
990         char *p = strrchr_m(path, sep);
991
992         if (p != NULL)
993                 *p = 0;
994
995         if (front != NULL)
996                 pstrcpy(front, path);
997
998         if (p != NULL) {
999                 if (back != NULL)
1000                         pstrcpy(back, p+1);
1001                 *p = '\\';
1002         } else {
1003                 if (back != NULL)
1004                         back[0] = 0;
1005         }
1006 }
1007
1008 /**
1009  Write an octal as a string.
1010 **/
1011
1012 const char *octal_string(int i)
1013 {
1014         static char ret[64];
1015         if (i == -1)
1016                 return "-1";
1017         slprintf(ret, sizeof(ret)-1, "0%o", i);
1018         return ret;
1019 }
1020
1021
1022 /**
1023  Truncate a string at a specified length.
1024 **/
1025
1026 char *string_truncate(char *s, int length)
1027 {
1028         if (s && strlen(s) > length)
1029                 s[length] = 0;
1030         return s;
1031 }
1032
1033 /**
1034  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1035  We convert via ucs2 for now.
1036 **/
1037
1038 char *strchr_m(const char *s, char c)
1039 {
1040         wpstring ws;
1041         pstring s2;
1042         smb_ucs2_t *p;
1043
1044         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1045         p = strchr_w(ws, UCS2_CHAR(c));
1046         if (!p)
1047                 return NULL;
1048         *p = 0;
1049         pull_ucs2_pstring(s2, ws);
1050         return (char *)(s+strlen(s2));
1051 }
1052
1053 char *strrchr_m(const char *s, char c)
1054 {
1055         wpstring ws;
1056         pstring s2;
1057         smb_ucs2_t *p;
1058
1059         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1060         p = strrchr_w(ws, UCS2_CHAR(c));
1061         if (!p)
1062                 return NULL;
1063         *p = 0;
1064         pull_ucs2_pstring(s2, ws);
1065         return (char *)(s+strlen(s2));
1066 }
1067
1068 /**
1069  Convert a string to lower case.
1070 **/
1071
1072 void strlower_m(char *s)
1073 {
1074         /* this is quite a common operation, so we want it to be
1075            fast. We optimise for the ascii case, knowing that all our
1076            supported multi-byte character sets are ascii-compatible
1077            (ie. they match for the first 128 chars) */
1078
1079         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1080                 *s = tolower((unsigned char)*s);
1081                 s++;
1082         }
1083
1084         if (!*s)
1085                 return;
1086
1087         /* I assume that lowercased string takes the same number of bytes
1088          * as source string even in UTF-8 encoding. (VIV) */
1089         unix_strlower(s,strlen(s)+1,s,strlen(s)+1);     
1090 }
1091
1092 /**
1093  Duplicate convert a string to lower case.
1094 **/
1095
1096 char *strdup_lower(const char *s)
1097 {
1098         char *t = strdup(s);
1099         if (t == NULL) {
1100                 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1101                 return NULL;
1102         }
1103         strlower_m(t);
1104         return t;
1105 }
1106
1107 /**
1108  Convert a string to upper case.
1109 **/
1110
1111 void strupper_m(char *s)
1112 {
1113         /* this is quite a common operation, so we want it to be
1114            fast. We optimise for the ascii case, knowing that all our
1115            supported multi-byte character sets are ascii-compatible
1116            (ie. they match for the first 128 chars) */
1117
1118         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1119                 *s = toupper((unsigned char)*s);
1120                 s++;
1121         }
1122
1123         if (!*s)
1124                 return;
1125
1126         /* I assume that lowercased string takes the same number of bytes
1127          * as source string even in multibyte encoding. (VIV) */
1128         unix_strupper(s,strlen(s)+1,s,strlen(s)+1);     
1129 }
1130
1131 /**
1132  Convert a string to upper case.
1133 **/
1134
1135 char *strdup_upper(const char *s)
1136 {
1137         char *t = strdup(s);
1138         if (t == NULL) {
1139                 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1140                 return NULL;
1141         }
1142         strupper_m(t);
1143         return t;
1144 }
1145
1146 /**
1147  Return a RFC2254 binary string representation of a buffer.
1148  Used in LDAP filters.
1149  Caller must free.
1150 **/
1151
1152 char *binary_string(char *buf, int len)
1153 {
1154         char *s;
1155         int i, j;
1156         const char *hex = "0123456789ABCDEF";
1157         s = malloc(len * 3 + 1);
1158         if (!s)
1159                 return NULL;
1160         for (j=i=0;i<len;i++) {
1161                 s[j] = '\\';
1162                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1163                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1164                 j += 3;
1165         }
1166         s[j] = 0;
1167         return s;
1168 }
1169
1170 /**
1171  Just a typesafety wrapper for snprintf into a pstring.
1172 **/
1173
1174  int pstr_sprintf(pstring s, const char *fmt, ...)
1175 {
1176         va_list ap;
1177         int ret;
1178
1179         va_start(ap, fmt);
1180         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1181         va_end(ap);
1182         return ret;
1183 }
1184
1185 /**
1186  Just a typesafety wrapper for snprintf into a fstring.
1187 **/
1188
1189  int fstr_sprintf(fstring s, const char *fmt, ...)
1190 {
1191         va_list ap;
1192         int ret;
1193
1194         va_start(ap, fmt);
1195         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1196         va_end(ap);
1197         return ret;
1198 }
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
1670 #ifdef VALGRIND
1671 size_t valgrind_strlen(const char *s)
1672 {
1673         size_t count;
1674         for(count = 0; *s++; count++)
1675                 ;
1676         return count;
1677 }
1678 #endif