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