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