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