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