Merge in the developer string options from HEAD. We need to ensure 3.0
[kai/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 void clobber_region(const char *fn, unsigned int line, char *dest, size_t len)
429 {
430 #ifdef DEVELOPER
431         /* F1 is odd and 0xf1f1f1f1 shouldn't be a valid pointer */
432         memset(dest, 0xF1, len);
433         global_clobber_region_function = fn;
434         global_clobber_region_line = line;
435 #endif
436 }
437
438
439 /**
440  Safe string copy into a known length string. maxlength does not
441  include the terminating zero.
442 **/
443
444 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
445 {
446         size_t len;
447
448         if (!dest) {
449                 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
450                 return NULL;
451         }
452
453         clobber_region(fn,line,dest, maxlength+1);
454
455         if (!src) {
456                 *dest = 0;
457                 return dest;
458         }  
459
460         len = strlen(src);
461
462         if (len > maxlength) {
463                 DEBUG(0,("ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s]\n",
464                          (unsigned int)(len-maxlength), len, maxlength, src));
465                 len = maxlength;
466         }
467       
468         memmove(dest, src, len);
469         dest[len] = 0;
470         return dest;
471 }  
472
473 /**
474  Safe string cat into a string. maxlength does not
475  include the terminating zero.
476 **/
477 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
478 {
479         size_t src_len, dest_len;
480
481         if (!dest) {
482                 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
483                 return NULL;
484         }
485
486         if (!src)
487                 return dest;
488         
489         src_len = strlen(src);
490         dest_len = strlen(dest);
491
492         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
493
494         if (src_len + dest_len > maxlength) {
495                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
496                          (int)(src_len + dest_len - maxlength), src));
497                 if (maxlength > dest_len) {
498                         memcpy(&dest[dest_len], src, maxlength - dest_len);
499                 }
500                 dest[maxlength] = 0;
501                 return NULL;
502         }
503
504         memcpy(&dest[dest_len], src, src_len);
505         dest[dest_len + src_len] = 0;
506         return dest;
507 }
508
509 /**
510  Paranoid strcpy into a buffer of given length (includes terminating
511  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
512  and replaces with '_'. Deliberately does *NOT* check for multibyte
513  characters. Don't change it !
514 **/
515 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
516 {
517         size_t len, i;
518
519         clobber_region(fn, line, dest, maxlength);
520
521         if (!dest) {
522                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
523                 return NULL;
524         }
525
526         if (!src) {
527                 *dest = 0;
528                 return dest;
529         }  
530
531         len = strlen(src);
532         if (len >= maxlength)
533                 len = maxlength - 1;
534
535         if (!other_safe_chars)
536                 other_safe_chars = "";
537
538         for(i = 0; i < len; i++) {
539                 int val = (src[i] & 0xff);
540                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
541                         dest[i] = src[i];
542                 else
543                         dest[i] = '_';
544         }
545
546         dest[i] = '\0';
547
548         return dest;
549 }
550
551 /**
552  Like strncpy but always null terminates. Make sure there is room!
553  The variable n should always be one less than the available size.
554 **/
555 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
556 {
557         char *d = dest;
558
559         clobber_region(fn, line, dest, n+1);
560
561         if (!dest)
562                 return(NULL);
563         
564         if (!src) {
565                 *dest = 0;
566                 return(dest);
567         }
568         while (n-- && (*d++ = *src++))
569                 ;
570         *d = 0;
571         return(dest);
572 }
573
574 #if 0
575 /**
576  Like strncpy but copies up to the character marker.  always null terminates.
577  returns a pointer to the character marker in the source string (src).
578 **/
579
580 static char *strncpyn(char *dest, const char *src, size_t n, char c)
581 {
582         char *p;
583         size_t str_len;
584
585         clobber_region(dest, n+1);
586
587         p = strchr_m(src, c);
588         if (p == NULL) {
589                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
590                 return NULL;
591         }
592
593         str_len = PTR_DIFF(p, src);
594         strncpy(dest, src, MIN(n, str_len));
595         dest[str_len] = '\0';
596
597         return p;
598 }
599 #endif
600
601 /**
602  Routine to get hex characters and turn them into a 16 byte array.
603  the array can be variable length, and any non-hex-numeric
604  characters are skipped.  "0xnn" or "0Xnn" is specially catered
605  for.
606
607  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
608
609 **/
610
611 size_t strhex_to_str(char *p, size_t len, const char *strhex)
612 {
613         size_t i;
614         size_t num_chars = 0;
615         unsigned char   lonybble, hinybble;
616         const char     *hexchars = "0123456789ABCDEF";
617         char           *p1 = NULL, *p2 = NULL;
618
619         for (i = 0; i < len && strhex[i] != 0; i++) {
620                 if (strnequal(hexchars, "0x", 2)) {
621                         i++; /* skip two chars */
622                         continue;
623                 }
624
625                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
626                         break;
627
628                 i++; /* next hex digit */
629
630                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
631                         break;
632
633                 /* get the two nybbles */
634                 hinybble = PTR_DIFF(p1, hexchars);
635                 lonybble = PTR_DIFF(p2, hexchars);
636
637                 p[num_chars] = (hinybble << 4) | lonybble;
638                 num_chars++;
639
640                 p1 = NULL;
641                 p2 = NULL;
642         }
643         return num_chars;
644 }
645
646 /**
647  Check if a string is part of a list.
648 **/
649
650 BOOL in_list(char *s,char *list,BOOL casesensitive)
651 {
652         pstring tok;
653         const char *p=list;
654
655         if (!list)
656                 return(False);
657
658         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
659                 if (casesensitive) {
660                         if (strcmp(tok,s) == 0)
661                                 return(True);
662                 } else {
663                         if (StrCaseCmp(tok,s) == 0)
664                                 return(True);
665                 }
666         }
667         return(False);
668 }
669
670 /* this is used to prevent lots of mallocs of size 1 */
671 static char *null_string = NULL;
672
673 /**
674  Set a string value, allocing the space for the string
675 **/
676
677 static BOOL string_init(char **dest,const char *src)
678 {
679         size_t l;
680         if (!src)     
681                 src = "";
682
683         l = strlen(src);
684
685         if (l == 0) {
686                 if (!null_string) {
687                         if((null_string = (char *)malloc(1)) == NULL) {
688                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
689                                 return False;
690                         }
691                         *null_string = 0;
692                 }
693                 *dest = null_string;
694         } else {
695                 (*dest) = strdup(src);
696                 if ((*dest) == NULL) {
697                         DEBUG(0,("Out of memory in string_init\n"));
698                         return False;
699                 }
700         }
701         return(True);
702 }
703
704 /**
705  Free a string value.
706 **/
707
708 void string_free(char **s)
709 {
710         if (!s || !(*s))
711                 return;
712         if (*s == null_string)
713                 *s = NULL;
714         SAFE_FREE(*s);
715 }
716
717 /**
718  Set a string value, deallocating any existing space, and allocing the space
719  for the string
720 **/
721
722 BOOL string_set(char **dest,const char *src)
723 {
724         string_free(dest);
725         return(string_init(dest,src));
726 }
727
728 /**
729  Substitute a string for a pattern in another string. Make sure there is 
730  enough room!
731
732  This routine looks for pattern in s and replaces it with 
733  insert. It may do multiple replacements.
734
735  Any of " ; ' $ or ` in the insert string are replaced with _
736  if len==0 then the string cannot be extended. This is different from the old
737  use of len==0 which was for no length checks to be done.
738 **/
739
740 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
741 {
742         char *p;
743         ssize_t ls,lp,li, i;
744
745         if (!insert || !pattern || !*pattern || !s)
746                 return;
747
748         ls = (ssize_t)strlen(s);
749         lp = (ssize_t)strlen(pattern);
750         li = (ssize_t)strlen(insert);
751
752         if (len == 0)
753                 len = ls + 1; /* len is number of *bytes* */
754
755         while (lp <= ls && (p = strstr(s,pattern))) {
756                 if (ls + (li-lp) >= len) {
757                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
758                                  (int)(ls + (li-lp) - len),
759                                  pattern, (int)len));
760                         break;
761                 }
762                 if (li != lp) {
763                         memmove(p+li,p+lp,strlen(p+lp)+1);
764                 }
765                 for (i=0;i<li;i++) {
766                         switch (insert[i]) {
767                         case '`':
768                         case '"':
769                         case '\'':
770                         case ';':
771                         case '$':
772                         case '%':
773                         case '\r':
774                         case '\n':
775                                 p[i] = '_';
776                                 break;
777                         default:
778                                 p[i] = insert[i];
779                         }
780                 }
781                 s = p + li;
782                 ls += (li-lp);
783         }
784 }
785
786 void fstring_sub(char *s,const char *pattern,const char *insert)
787 {
788         string_sub(s, pattern, insert, sizeof(fstring));
789 }
790
791 void pstring_sub(char *s,const char *pattern,const char *insert)
792 {
793         string_sub(s, pattern, insert, sizeof(pstring));
794 }
795
796 /**
797  Similar to string_sub, but it will accept only allocated strings
798  and may realloc them so pay attention at what you pass on no
799  pointers inside strings, no pstrings or const may be passed
800  as string.
801 **/
802
803 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
804 {
805         char *p, *in;
806         char *s;
807         ssize_t ls,lp,li,ld, i;
808
809         if (!insert || !pattern || !*pattern || !string || !*string)
810                 return NULL;
811
812         s = string;
813
814         in = strdup(insert);
815         if (!in) {
816                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
817                 return NULL;
818         }
819         ls = (ssize_t)strlen(s);
820         lp = (ssize_t)strlen(pattern);
821         li = (ssize_t)strlen(insert);
822         ld = li - lp;
823         for (i=0;i<li;i++) {
824                 switch (in[i]) {
825                         case '`':
826                         case '"':
827                         case '\'':
828                         case ';':
829                         case '$':
830                         case '%':
831                         case '\r':
832                         case '\n':
833                                 in[i] = '_';
834                         default:
835                                 /* ok */
836                                 break;
837                 }
838         }
839         
840         while ((p = strstr(s,pattern))) {
841                 if (ld > 0) {
842                         char *t = Realloc(string, ls + ld + 1);
843                         if (!t) {
844                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
845                                 SAFE_FREE(in);
846                                 return NULL;
847                         }
848                         string = t;
849                         p = t + (p - s);
850                 }
851                 if (li != lp) {
852                         memmove(p+li,p+lp,strlen(p+lp)+1);
853                 }
854                 memcpy(p, in, li);
855                 s = p + li;
856                 ls += ld;
857         }
858         SAFE_FREE(in);
859         return string;
860 }
861
862 /**
863  Similar to string_sub() but allows for any character to be substituted. 
864  Use with caution!
865  if len==0 then the string cannot be extended. This is different from the old
866  use of len==0 which was for no length checks to be done.
867 **/
868
869 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
870 {
871         char *p;
872         ssize_t ls,lp,li;
873
874         if (!insert || !pattern || !s)
875                 return;
876
877         ls = (ssize_t)strlen(s);
878         lp = (ssize_t)strlen(pattern);
879         li = (ssize_t)strlen(insert);
880
881         if (!*pattern)
882                 return;
883         
884         if (len == 0)
885                 len = ls + 1; /* len is number of *bytes* */
886         
887         while (lp <= ls && (p = strstr(s,pattern))) {
888                 if (ls + (li-lp) >= len) {
889                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
890                                  (int)(ls + (li-lp) - len),
891                                  pattern, (int)len));
892                         break;
893                 }
894                 if (li != lp) {
895                         memmove(p+li,p+lp,strlen(p+lp)+1);
896                 }
897                 memcpy(p, insert, li);
898                 s = p + li;
899                 ls += (li-lp);
900         }
901 }
902
903 /**
904  Similar to all_string_sub but for unicode strings.
905  Return a new allocated unicode string.
906  similar to string_sub() but allows for any character to be substituted.
907  Use with caution!
908 **/
909
910 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
911                                 const smb_ucs2_t *insert)
912 {
913         smb_ucs2_t *r, *rp;
914         const smb_ucs2_t *sp;
915         size_t  lr, lp, li, lt;
916
917         if (!insert || !pattern || !*pattern || !s)
918                 return NULL;
919
920         lt = (size_t)strlen_w(s);
921         lp = (size_t)strlen_w(pattern);
922         li = (size_t)strlen_w(insert);
923
924         if (li > lp) {
925                 const smb_ucs2_t *st = s;
926                 int ld = li - lp;
927                 while ((sp = strstr_w(st, pattern))) {
928                         st = sp + lp;
929                         lt += ld;
930                 }
931         }
932
933         r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
934         if (!r) {
935                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
936                 return NULL;
937         }
938
939         while ((sp = strstr_w(s, pattern))) {
940                 memcpy(rp, s, (sp - s));
941                 rp += ((sp - s) / sizeof(smb_ucs2_t));
942                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
943                 s = sp + lp;
944                 rp += li;
945         }
946         lr = ((rp - r) / sizeof(smb_ucs2_t));
947         if (lr < lt) {
948                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
949                 rp += (lt - lr);
950         }
951         *rp = 0;
952
953         return r;
954 }
955
956 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
957                                              const char *insert)
958 {
959         wpstring p, i;
960
961         if (!insert || !pattern || !s)
962                 return NULL;
963         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
964         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
965         return all_string_sub_w(s, p, i);
966 }
967
968 #if 0
969 /**
970  Splits out the front and back at a separator.
971 **/
972
973 static void split_at_last_component(char *path, char *front, char sep, char *back)
974 {
975         char *p = strrchr_m(path, sep);
976
977         if (p != NULL)
978                 *p = 0;
979
980         if (front != NULL)
981                 pstrcpy(front, path);
982
983         if (p != NULL) {
984                 if (back != NULL)
985                         pstrcpy(back, p+1);
986                 *p = '\\';
987         } else {
988                 if (back != NULL)
989                         back[0] = 0;
990         }
991 }
992 #endif
993
994 /**
995  Write an octal as a string.
996 **/
997
998 const char *octal_string(int i)
999 {
1000         static char ret[64];
1001         if (i == -1)
1002                 return "-1";
1003         slprintf(ret, sizeof(ret)-1, "0%o", i);
1004         return ret;
1005 }
1006
1007
1008 /**
1009  Truncate a string at a specified length.
1010 **/
1011
1012 char *string_truncate(char *s, unsigned int length)
1013 {
1014         if (s && strlen(s) > length)
1015                 s[length] = 0;
1016         return s;
1017 }
1018
1019 /**
1020  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1021  We convert via ucs2 for now.
1022 **/
1023
1024 char *strchr_m(const char *s, char c)
1025 {
1026         wpstring ws;
1027         pstring s2;
1028         smb_ucs2_t *p;
1029
1030         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1031         p = strchr_w(ws, UCS2_CHAR(c));
1032         if (!p)
1033                 return NULL;
1034         *p = 0;
1035         pull_ucs2_pstring(s2, ws);
1036         return (char *)(s+strlen(s2));
1037 }
1038
1039 char *strrchr_m(const char *s, char c)
1040 {
1041         wpstring ws;
1042         pstring s2;
1043         smb_ucs2_t *p;
1044
1045         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1046         p = strrchr_w(ws, UCS2_CHAR(c));
1047         if (!p)
1048                 return NULL;
1049         *p = 0;
1050         pull_ucs2_pstring(s2, ws);
1051         return (char *)(s+strlen(s2));
1052 }
1053
1054 /**
1055  Convert a string to lower case.
1056 **/
1057
1058 void strlower_m(char *s)
1059 {
1060         /* this is quite a common operation, so we want it to be
1061            fast. We optimise for the ascii case, knowing that all our
1062            supported multi-byte character sets are ascii-compatible
1063            (ie. they match for the first 128 chars) */
1064
1065         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1066                 *s = tolower((unsigned char)*s);
1067                 s++;
1068         }
1069
1070         if (!*s)
1071                 return;
1072
1073         /* I assume that lowercased string takes the same number of bytes
1074          * as source string even in UTF-8 encoding. (VIV) */
1075         unix_strlower(s,strlen(s)+1,s,strlen(s)+1);     
1076 }
1077
1078 /**
1079  Duplicate convert a string to lower case.
1080 **/
1081
1082 char *strdup_lower(const char *s)
1083 {
1084         char *t = strdup(s);
1085         if (t == NULL) {
1086                 DEBUG(0, ("strdup_lower: Out of memory!\n"));
1087                 return NULL;
1088         }
1089         strlower_m(t);
1090         return t;
1091 }
1092
1093 /**
1094  Convert a string to upper case.
1095 **/
1096
1097 void strupper_m(char *s)
1098 {
1099         /* this is quite a common operation, so we want it to be
1100            fast. We optimise for the ascii case, knowing that all our
1101            supported multi-byte character sets are ascii-compatible
1102            (ie. they match for the first 128 chars) */
1103
1104         while (*s && !(((unsigned char)s[0]) & 0x7F)) {
1105                 *s = toupper((unsigned char)*s);
1106                 s++;
1107         }
1108
1109         if (!*s)
1110                 return;
1111
1112         /* I assume that lowercased string takes the same number of bytes
1113          * as source string even in multibyte encoding. (VIV) */
1114         unix_strupper(s,strlen(s)+1,s,strlen(s)+1);     
1115 }
1116
1117 /**
1118  Convert a string to upper case.
1119 **/
1120
1121 char *strdup_upper(const char *s)
1122 {
1123         char *t = strdup(s);
1124         if (t == NULL) {
1125                 DEBUG(0, ("strdup_upper: Out of memory!\n"));
1126                 return NULL;
1127         }
1128         strupper_m(t);
1129         return t;
1130 }
1131
1132 /**
1133  Return a RFC2254 binary string representation of a buffer.
1134  Used in LDAP filters.
1135  Caller must free.
1136 **/
1137
1138 char *binary_string(char *buf, int len)
1139 {
1140         char *s;
1141         int i, j;
1142         const char *hex = "0123456789ABCDEF";
1143         s = malloc(len * 3 + 1);
1144         if (!s)
1145                 return NULL;
1146         for (j=i=0;i<len;i++) {
1147                 s[j] = '\\';
1148                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1149                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1150                 j += 3;
1151         }
1152         s[j] = 0;
1153         return s;
1154 }
1155
1156 /**
1157  Just a typesafety wrapper for snprintf into a pstring.
1158 **/
1159
1160  int pstr_sprintf(pstring s, const char *fmt, ...)
1161 {
1162         va_list ap;
1163         int ret;
1164
1165         va_start(ap, fmt);
1166         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1167         va_end(ap);
1168         return ret;
1169 }
1170
1171 #if 0
1172 /**
1173  Just a typesafety wrapper for snprintf into a fstring.
1174 **/
1175
1176 static int fstr_sprintf(fstring s, const char *fmt, ...)
1177 {
1178         va_list ap;
1179         int ret;
1180
1181         va_start(ap, fmt);
1182         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1183         va_end(ap);
1184         return ret;
1185 }
1186 #endif
1187
1188 #ifndef HAVE_STRNDUP
1189 /**
1190  Some platforms don't have strndup.
1191 **/
1192
1193  char *strndup(const char *s, size_t n)
1194 {
1195         char *ret;
1196         
1197         n = strnlen(s, n);
1198         ret = malloc(n+1);
1199         if (!ret)
1200                 return NULL;
1201         memcpy(ret, s, n);
1202         ret[n] = 0;
1203
1204         return ret;
1205 }
1206 #endif
1207
1208 #ifndef HAVE_STRNLEN
1209 /**
1210  Some platforms don't have strnlen
1211 **/
1212
1213  size_t strnlen(const char *s, size_t n)
1214 {
1215         int i;
1216         for (i=0; s[i] && i<n; i++)
1217                 /* noop */ ;
1218         return i;
1219 }
1220 #endif
1221
1222 /**
1223  List of Strings manipulation functions
1224 **/
1225
1226 #define S_LIST_ABS 16 /* List Allocation Block Size */
1227
1228 char **str_list_make(const char *string, const char *sep)
1229 {
1230         char **list, **rlist;
1231         const char *str;
1232         char *s;
1233         int num, lsize;
1234         pstring tok;
1235         
1236         if (!string || !*string)
1237                 return NULL;
1238         s = strdup(string);
1239         if (!s) {
1240                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1241                 return NULL;
1242         }
1243         if (!sep) sep = LIST_SEP;
1244         
1245         num = lsize = 0;
1246         list = NULL;
1247         
1248         str = s;
1249         while (next_token(&str, tok, sep, sizeof(tok))) {               
1250                 if (num == lsize) {
1251                         lsize += S_LIST_ABS;
1252                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1253                         if (!rlist) {
1254                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1255                                 str_list_free(&list);
1256                                 SAFE_FREE(s);
1257                                 return NULL;
1258                         } else
1259                                 list = rlist;
1260                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1261                 }
1262                 
1263                 list[num] = strdup(tok);
1264                 if (!list[num]) {
1265                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1266                         str_list_free(&list);
1267                         SAFE_FREE(s);
1268                         return NULL;
1269                 }
1270         
1271                 num++;  
1272         }
1273         
1274         SAFE_FREE(s);
1275         return list;
1276 }
1277
1278 BOOL str_list_copy(char ***dest, const char **src)
1279 {
1280         char **list, **rlist;
1281         int num, lsize;
1282         
1283         *dest = NULL;
1284         if (!src)
1285                 return False;
1286         
1287         num = lsize = 0;
1288         list = NULL;
1289                 
1290         while (src[num]) {
1291                 if (num == lsize) {
1292                         lsize += S_LIST_ABS;
1293                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1294                         if (!rlist) {
1295                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1296                                 str_list_free(&list);
1297                                 return False;
1298                         } else
1299                                 list = rlist;
1300                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1301                 }
1302                 
1303                 list[num] = strdup(src[num]);
1304                 if (!list[num]) {
1305                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1306                         str_list_free(&list);
1307                         return False;
1308                 }
1309
1310                 num++;
1311         }
1312         
1313         *dest = list;
1314         return True;    
1315 }
1316
1317 /**
1318  * Return true if all the elements of the list match exactly.
1319  **/
1320 BOOL str_list_compare(char **list1, char **list2)
1321 {
1322         int num;
1323         
1324         if (!list1 || !list2)
1325                 return (list1 == list2); 
1326         
1327         for (num = 0; list1[num]; num++) {
1328                 if (!list2[num])
1329                         return False;
1330                 if (!strcsequal(list1[num], list2[num]))
1331                         return False;
1332         }
1333         if (list2[num])
1334                 return False; /* if list2 has more elements than list1 fail */
1335         
1336         return True;
1337 }
1338
1339 void str_list_free(char ***list)
1340 {
1341         char **tlist;
1342         
1343         if (!list || !*list)
1344                 return;
1345         tlist = *list;
1346         for(; *tlist; tlist++)
1347                 SAFE_FREE(*tlist);
1348         SAFE_FREE(*list);
1349 }
1350
1351 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1352 {
1353         char *p, *s, *t;
1354         ssize_t ls, lp, li, ld, i, d;
1355
1356         if (!list)
1357                 return False;
1358         if (!pattern)
1359                 return False;
1360         if (!insert)
1361                 return False;
1362
1363         lp = (ssize_t)strlen(pattern);
1364         li = (ssize_t)strlen(insert);
1365         ld = li -lp;
1366                         
1367         while (*list) {
1368                 s = *list;
1369                 ls = (ssize_t)strlen(s);
1370
1371                 while ((p = strstr(s, pattern))) {
1372                         t = *list;
1373                         d = p -t;
1374                         if (ld) {
1375                                 t = (char *) malloc(ls +ld +1);
1376                                 if (!t) {
1377                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1378                                         return False;
1379                                 }
1380                                 memcpy(t, *list, d);
1381                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1382                                 SAFE_FREE(*list);
1383                                 *list = t;
1384                                 ls += ld;
1385                                 s = t +d +li;
1386                         }
1387                         
1388                         for (i = 0; i < li; i++) {
1389                                 switch (insert[i]) {
1390                                         case '`':
1391                                         case '"':
1392                                         case '\'':
1393                                         case ';':
1394                                         case '$':
1395                                         case '%':
1396                                         case '\r':
1397                                         case '\n':
1398                                                 t[d +i] = '_';
1399                                                 break;
1400                                         default:
1401                                                 t[d +i] = insert[i];
1402                                 }
1403                         }       
1404                 }
1405                 
1406                 list++;
1407         }
1408         
1409         return True;
1410 }
1411
1412
1413 #define IPSTR_LIST_SEP  ","
1414
1415 /**
1416  * Add ip string representation to ipstr list. Used also
1417  * as part of @function ipstr_list_make
1418  *
1419  * @param ipstr_list pointer to string containing ip list;
1420  *        MUST BE already allocated and IS reallocated if necessary
1421  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1422  *        as a result of reallocation)
1423  * @param ip IP address which is to be added to list
1424  * @return pointer to string appended with new ip and possibly
1425  *         reallocated to new length
1426  **/
1427
1428 char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
1429 {
1430         char* new_ipstr = NULL;
1431         
1432         /* arguments checking */
1433         if (!ipstr_list || !ip) return NULL;
1434
1435         /* attempt to convert ip to a string and append colon separator to it */
1436         if (*ipstr_list) {
1437                 asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
1438                 SAFE_FREE(*ipstr_list);
1439         } else {
1440                 asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
1441         }
1442         *ipstr_list = new_ipstr;
1443         return *ipstr_list;
1444 }
1445
1446
1447 /**
1448  * Allocate and initialise an ipstr list using ip adresses
1449  * passed as arguments.
1450  *
1451  * @param ipstr_list pointer to string meant to be allocated and set
1452  * @param ip_list array of ip addresses to place in the list
1453  * @param ip_count number of addresses stored in ip_list
1454  * @return pointer to allocated ip string
1455  **/
1456  
1457 char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
1458 {
1459         int i;
1460         
1461         /* arguments checking */
1462         if (!ip_list && !ipstr_list) return 0;
1463
1464         *ipstr_list = NULL;
1465         
1466         /* process ip addresses given as arguments */
1467         for (i = 0; i < ip_count; i++)
1468                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1469         
1470         return (*ipstr_list);
1471 }
1472
1473
1474 /**
1475  * Parse given ip string list into array of ip addresses
1476  * (as in_addr structures)
1477  *
1478  * @param ipstr ip string list to be parsed 
1479  * @param ip_list pointer to array of ip addresses which is
1480  *        allocated by this function and must be freed by caller
1481  * @return number of succesfully parsed addresses
1482  **/
1483  
1484 int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
1485 {
1486         fstring token_str;
1487         int count;
1488
1489         if (!ipstr_list || !ip_list) return 0;
1490         
1491         for (*ip_list = NULL, count = 0;
1492              next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
1493              count++) {
1494              
1495                 struct in_addr addr;
1496
1497                 /* convert single token to ip address */
1498                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1499                         break;
1500                 
1501                 /* prepare place for another in_addr structure */
1502                 *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
1503                 if (!*ip_list) return -1;
1504                 
1505                 (*ip_list)[count] = addr;
1506         }
1507         
1508         return count;
1509 }
1510
1511
1512 /**
1513  * Safely free ip string list
1514  *
1515  * @param ipstr_list ip string list to be freed
1516  **/
1517
1518 void ipstr_list_free(char* ipstr_list)
1519 {
1520         SAFE_FREE(ipstr_list);
1521 }
1522
1523
1524 /**
1525  Unescape a URL encoded string, in place.
1526 **/
1527
1528 void rfc1738_unescape(char *buf)
1529 {
1530         char *p=buf;
1531
1532         while ((p=strchr_m(p,'+')))
1533                 *p = ' ';
1534
1535         p = buf;
1536
1537         while (p && *p && (p=strchr_m(p,'%'))) {
1538                 int c1 = p[1];
1539                 int c2 = p[2];
1540
1541                 if (c1 >= '0' && c1 <= '9')
1542                         c1 = c1 - '0';
1543                 else if (c1 >= 'A' && c1 <= 'F')
1544                         c1 = 10 + c1 - 'A';
1545                 else if (c1 >= 'a' && c1 <= 'f')
1546                         c1 = 10 + c1 - 'a';
1547                 else {p++; continue;}
1548
1549                 if (c2 >= '0' && c2 <= '9')
1550                         c2 = c2 - '0';
1551                 else if (c2 >= 'A' && c2 <= 'F')
1552                         c2 = 10 + c2 - 'A';
1553                 else if (c2 >= 'a' && c2 <= 'f')
1554                         c2 = 10 + c2 - 'a';
1555                 else {p++; continue;}
1556                         
1557                 *p = (c1<<4) | c2;
1558
1559                 memmove(p+1, p+3, strlen(p+3)+1);
1560                 p++;
1561         }
1562 }
1563
1564 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1565
1566 /**
1567  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1568  **/
1569 DATA_BLOB base64_decode_data_blob(const char *s)
1570 {
1571         int bit_offset, byte_offset, idx, i, n;
1572         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1573         unsigned char *d = decoded.data;
1574         char *p;
1575
1576         n=i=0;
1577
1578         while (*s && (p=strchr_m(b64,*s))) {
1579                 idx = (int)(p - b64);
1580                 byte_offset = (i*6)/8;
1581                 bit_offset = (i*6)%8;
1582                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1583                 if (bit_offset < 3) {
1584                         d[byte_offset] |= (idx << (2-bit_offset));
1585                         n = byte_offset+1;
1586                 } else {
1587                         d[byte_offset] |= (idx >> (bit_offset-2));
1588                         d[byte_offset+1] = 0;
1589                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1590                         n = byte_offset+2;
1591                 }
1592                 s++; i++;
1593         }
1594
1595         /* fix up length */
1596         decoded.length = n;
1597         return decoded;
1598 }
1599
1600 /**
1601  * Decode a base64 string in-place - wrapper for the above
1602  **/
1603 void base64_decode_inplace(char *s)
1604 {
1605         DATA_BLOB decoded = base64_decode_data_blob(s);
1606         memcpy(s, decoded.data, decoded.length);
1607         data_blob_free(&decoded);
1608
1609         /* null terminate */
1610         s[decoded.length] = '\0';
1611 }
1612
1613 /**
1614  * Encode a base64 string into a malloc()ed string caller to free.
1615  *
1616  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1617  **/
1618 char * base64_encode_data_blob(DATA_BLOB data)
1619 {
1620         int bits = 0;
1621         int char_count = 0;
1622         size_t out_cnt = 0;
1623         size_t len = data.length;
1624         size_t output_len = data.length * 2;
1625         char *result = malloc(output_len); /* get us plenty of space */
1626
1627         while (len-- && out_cnt < (data.length * 2) - 5) {
1628                 int c = (unsigned char) *(data.data++);
1629                 bits += c;
1630                 char_count++;
1631                 if (char_count == 3) {
1632                         result[out_cnt++] = b64[bits >> 18];
1633                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1634                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1635             result[out_cnt++] = b64[bits & 0x3f];
1636             bits = 0;
1637             char_count = 0;
1638         } else {
1639             bits <<= 8;
1640         }
1641     }
1642     if (char_count != 0) {
1643         bits <<= 16 - (8 * char_count);
1644         result[out_cnt++] = b64[bits >> 18];
1645         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1646         if (char_count == 1) {
1647             result[out_cnt++] = '=';
1648             result[out_cnt++] = '=';
1649         } else {
1650             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1651             result[out_cnt++] = '=';
1652         }
1653     }
1654     result[out_cnt] = '\0';     /* terminate */
1655     return result;
1656 }
1657