r15305: Let winbind search by sid directly (or in windows terms: "bind to a
[samba.git] / source / 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         char *s;
41         char *pbuf;
42         BOOL quoted;
43         size_t len=1;
44
45         if (!ptr)
46                 return(False);
47
48         s = (char *)*ptr;
49
50         /* default to simple separators */
51         if (!sep)
52                 sep = " \t\n\r";
53
54         /* find the first non sep char */
55         while (*s && strchr_m(sep,*s))
56                 s++;
57         
58         /* nothing left? */
59         if (! *s)
60                 return(False);
61         
62         /* copy over the token */
63         pbuf = buff;
64         for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
65                 if ( *s == '\"' ) {
66                         quoted = !quoted;
67                 } else {
68                         len++;
69                         *pbuf++ = *s;
70                 }
71         }
72         
73         *ptr = (*s) ? s+1 : s;  
74         *pbuf = 0;
75         
76         return(True);
77 }
78
79 /**
80 This is like next_token but is not re-entrant and "remembers" the first 
81 parameter so you can pass NULL. This is useful for user interface code
82 but beware the fact that it is not re-entrant!
83 **/
84
85 static const char *last_ptr=NULL;
86
87 BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
88 {
89         BOOL ret;
90         if (!ptr)
91                 ptr = &last_ptr;
92
93         ret = next_token(ptr, buff, sep, bufsize);
94         last_ptr = *ptr;
95         return ret;     
96 }
97
98 static uint16 tmpbuf[sizeof(pstring)];
99
100 void set_first_token(char *ptr)
101 {
102         last_ptr = ptr;
103 }
104
105 /**
106  Convert list of tokens to array; dependent on above routine.
107  Uses last_ptr from above - bit of a hack.
108 **/
109
110 char **toktocliplist(int *ctok, const char *sep)
111 {
112         char *s=(char *)last_ptr;
113         int ictok=0;
114         char **ret, **iret;
115
116         if (!sep)
117                 sep = " \t\n\r";
118
119         while(*s && strchr_m(sep,*s))
120                 s++;
121
122         /* nothing left? */
123         if (!*s)
124                 return(NULL);
125
126         do {
127                 ictok++;
128                 while(*s && (!strchr_m(sep,*s)))
129                         s++;
130                 while(*s && strchr_m(sep,*s))
131                         *s++=0;
132         } while(*s);
133         
134         *ctok=ictok;
135         s=(char *)last_ptr;
136         
137         if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
138                 return NULL;
139         
140         while(ictok--) {    
141                 *iret++=s;
142                 if (ictok > 0) {
143                         while(*s++)
144                                 ;
145                         while(!*s)
146                                 s++;
147                 }
148         }
149
150         ret[*ctok] = NULL;
151         return ret;
152 }
153
154 /**
155  * Case insensitive string compararison.
156  *
157  * iconv does not directly give us a way to compare strings in
158  * arbitrary unix character sets -- all we can is convert and then
159  * compare.  This is expensive.
160  *
161  * As an optimization, we do a first pass that considers only the
162  * prefix of the strings that is entirely 7-bit.  Within this, we
163  * check whether they have the same value.
164  *
165  * Hopefully this will often give the answer without needing to copy.
166  * In particular it should speed comparisons to literal ascii strings
167  * or comparisons of strings that are "obviously" different.
168  *
169  * If we find a non-ascii character we fall back to converting via
170  * iconv.
171  *
172  * This should never be slower than convering the whole thing, and
173  * often faster.
174  *
175  * A different optimization would be to compare for bitwise equality
176  * in the binary encoding.  (It would be possible thought hairy to do
177  * both simultaneously.)  But in that case if they turn out to be
178  * different, we'd need to restart the whole thing.
179  *
180  * Even better is to implement strcasecmp for each encoding and use a
181  * function pointer. 
182  **/
183 int StrCaseCmp(const char *s, const char *t)
184 {
185
186         const char *ps, *pt;
187         size_t size;
188         smb_ucs2_t *buffer_s, *buffer_t;
189         int ret;
190
191         for (ps = s, pt = t; ; ps++, pt++) {
192                 char us, ut;
193
194                 if (!*ps && !*pt)
195                         return 0; /* both ended */
196                 else if (!*ps)
197                         return -1; /* s is a prefix */
198                 else if (!*pt)
199                         return +1; /* t is a prefix */
200                 else if ((*ps & 0x80) || (*pt & 0x80))
201                         /* not ascii anymore, do it the hard way from here on in */
202                         break;
203
204                 us = toupper_ascii(*ps);
205                 ut = toupper_ascii(*pt);
206                 if (us == ut)
207                         continue;
208                 else if (us < ut)
209                         return -1;
210                 else if (us > ut)
211                         return +1;
212         }
213
214         size = push_ucs2_allocate(&buffer_s, ps);
215         if (size == (size_t)-1) {
216                 return strcmp(ps, pt); 
217                 /* Not quite the right answer, but finding the right one
218                    under this failure case is expensive, and it's pretty close */
219         }
220         
221         size = push_ucs2_allocate(&buffer_t, pt);
222         if (size == (size_t)-1) {
223                 SAFE_FREE(buffer_s);
224                 return strcmp(ps, pt); 
225                 /* Not quite the right answer, but finding the right one
226                    under this failure case is expensive, and it's pretty close */
227         }
228         
229         ret = strcasecmp_w(buffer_s, buffer_t);
230         SAFE_FREE(buffer_s);
231         SAFE_FREE(buffer_t);
232         return ret;
233 }
234
235
236 /**
237  Case insensitive string compararison, length limited.
238 **/
239 int StrnCaseCmp(const char *s, const char *t, size_t n)
240 {
241         pstring buf1, buf2;
242         unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
243         unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
244         return strncmp(buf1,buf2,n);
245 }
246
247 /**
248  * Compare 2 strings.
249  *
250  * @note The comparison is case-insensitive.
251  **/
252 BOOL strequal(const char *s1, const char *s2)
253 {
254         if (s1 == s2)
255                 return(True);
256         if (!s1 || !s2)
257                 return(False);
258   
259         return(StrCaseCmp(s1,s2)==0);
260 }
261
262 /**
263  * Compare 2 strings up to and including the nth char.
264  *
265  * @note The comparison is case-insensitive.
266  **/
267 BOOL strnequal(const char *s1,const char *s2,size_t n)
268 {
269         if (s1 == s2)
270                 return(True);
271         if (!s1 || !s2 || !n)
272                 return(False);
273   
274         return(StrnCaseCmp(s1,s2,n)==0);
275 }
276
277 /**
278  Compare 2 strings (case sensitive).
279 **/
280
281 BOOL strcsequal(const char *s1,const char *s2)
282 {
283         if (s1 == s2)
284                 return(True);
285         if (!s1 || !s2)
286                 return(False);
287   
288         return(strcmp(s1,s2)==0);
289 }
290
291 /**
292 Do a case-insensitive, whitespace-ignoring string compare.
293 **/
294
295 int strwicmp(const char *psz1, const char *psz2)
296 {
297         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
298         /* appropriate value. */
299         if (psz1 == psz2)
300                 return (0);
301         else if (psz1 == NULL)
302                 return (-1);
303         else if (psz2 == NULL)
304                 return (1);
305
306         /* sync the strings on first non-whitespace */
307         while (1) {
308                 while (isspace((int)*psz1))
309                         psz1++;
310                 while (isspace((int)*psz2))
311                         psz2++;
312                 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
313                     || *psz2 == '\0')
314                         break;
315                 psz1++;
316                 psz2++;
317         }
318         return (*psz1 - *psz2);
319 }
320
321
322 /**
323  Convert a string to upper case, but don't modify it.
324 **/
325
326 char *strupper_static(const char *s)
327 {
328         static pstring str;
329
330         pstrcpy(str, s);
331         strupper_m(str);
332
333         return str;
334 }
335
336 /**
337  Convert a string to "normal" form.
338 **/
339
340 void strnorm(char *s, int case_default)
341 {
342         if (case_default == CASE_UPPER)
343                 strupper_m(s);
344         else
345                 strlower_m(s);
346 }
347
348 /**
349  Check if a string is in "normal" case.
350 **/
351
352 BOOL strisnormal(const char *s, int case_default)
353 {
354         if (case_default == CASE_UPPER)
355                 return(!strhaslower(s));
356         
357         return(!strhasupper(s));
358 }
359
360
361 /**
362  String replace.
363  NOTE: oldc and newc must be 7 bit characters
364 **/
365
366 void string_replace( pstring s, char oldc, char newc )
367 {
368         char *p;
369
370         /* this is quite a common operation, so we want it to be
371            fast. We optimise for the ascii case, knowing that all our
372            supported multi-byte character sets are ascii-compatible
373            (ie. they match for the first 128 chars) */
374
375         for (p = s; *p; p++) {
376                 if (*p & 0x80) /* mb string - slow path. */
377                         break;
378                 if (*p == oldc)
379                         *p = newc;
380         }
381
382         if (!*p)
383                 return;
384
385         /* Slow (mb) path. */
386 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
387         /* With compose characters we must restart from the beginning. JRA. */
388         p = s;
389 #endif
390         push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
391         string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
392         pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
393 }
394
395 /**
396  Skip past some strings in a buffer.
397 **/
398
399 char *skip_string(char *buf,size_t n)
400 {
401         while (n--)
402                 buf += strlen(buf) + 1;
403         return(buf);
404 }
405
406 /**
407  Count the number of characters in a string. Normally this will
408  be the same as the number of bytes in a string for single byte strings,
409  but will be different for multibyte.
410 **/
411
412 size_t str_charnum(const char *s)
413 {
414         uint16 tmpbuf2[sizeof(pstring)];
415         push_ucs2(NULL, tmpbuf2,s, sizeof(tmpbuf2), STR_TERMINATE);
416         return strlen_w(tmpbuf2);
417 }
418
419 /**
420  Count the number of characters in a string. Normally this will
421  be the same as the number of bytes in a string for single byte strings,
422  but will be different for multibyte.
423 **/
424
425 size_t str_ascii_charnum(const char *s)
426 {
427         pstring tmpbuf2;
428         push_ascii(tmpbuf2, s, sizeof(tmpbuf2), STR_TERMINATE);
429         return strlen(tmpbuf2);
430 }
431
432 BOOL trim_char(char *s,char cfront,char cback)
433 {
434         BOOL ret = False;
435         char *ep;
436         char *fp = s;
437
438         /* Ignore null or empty strings. */
439         if (!s || (s[0] == '\0'))
440                 return False;
441
442         if (cfront) {
443                 while (*fp && *fp == cfront)
444                         fp++;
445                 if (!*fp) {
446                         /* We ate the string. */
447                         s[0] = '\0';
448                         return True;
449                 }
450                 if (fp != s)
451                         ret = True;
452         }
453
454         ep = fp + strlen(fp) - 1;
455         if (cback) {
456                 /* Attempt ascii only. Bail for mb strings. */
457                 while ((ep >= fp) && (*ep == cback)) {
458                         ret = True;
459                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
460                                 /* Could be mb... bail back to tim_string. */
461                                 char fs[2], bs[2];
462                                 if (cfront) {
463                                         fs[0] = cfront;
464                                         fs[1] = '\0';
465                                 }
466                                 bs[0] = cback;
467                                 bs[1] = '\0';
468                                 return trim_string(s, cfront ? fs : NULL, bs);
469                         } else {
470                                 ep--;
471                         }
472                 }
473                 if (ep < fp) {
474                         /* We ate the string. */
475                         s[0] = '\0';
476                         return True;
477                 }
478         }
479
480         ep[1] = '\0';
481         memmove(s, fp, ep-fp+2);
482         return ret;
483 }
484
485 /**
486  Trim the specified elements off the front and back of a string.
487 **/
488
489 BOOL trim_string(char *s,const char *front,const char *back)
490 {
491         BOOL ret = False;
492         size_t front_len;
493         size_t back_len;
494         size_t len;
495
496         /* Ignore null or empty strings. */
497         if (!s || (s[0] == '\0'))
498                 return False;
499
500         front_len       = front? strlen(front) : 0;
501         back_len        = back? strlen(back) : 0;
502
503         len = strlen(s);
504
505         if (front_len) {
506                 while (len && strncmp(s, front, front_len)==0) {
507                         /* Must use memmove here as src & dest can
508                          * easily overlap. Found by valgrind. JRA. */
509                         memmove(s, s+front_len, (len-front_len)+1);
510                         len -= front_len;
511                         ret=True;
512                 }
513         }
514         
515         if (back_len) {
516                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
517                         s[len-back_len]='\0';
518                         len -= back_len;
519                         ret=True;
520                 }
521         }
522         return ret;
523 }
524
525 /**
526  Does a string have any uppercase chars in it?
527 **/
528
529 BOOL strhasupper(const char *s)
530 {
531         smb_ucs2_t *ptr;
532         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
533         for(ptr=tmpbuf;*ptr;ptr++)
534                 if(isupper_w(*ptr))
535                         return True;
536         return(False);
537 }
538
539 /**
540  Does a string have any lowercase chars in it?
541 **/
542
543 BOOL strhaslower(const char *s)
544 {
545         smb_ucs2_t *ptr;
546         push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
547         for(ptr=tmpbuf;*ptr;ptr++)
548                 if(islower_w(*ptr))
549                         return True;
550         return(False);
551 }
552
553 /**
554  Find the number of 'c' chars in a string
555 **/
556
557 size_t count_chars(const char *s,char c)
558 {
559         smb_ucs2_t *ptr;
560         int count;
561         smb_ucs2_t *alloc_tmpbuf = NULL;
562
563         if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
564                 return 0;
565         }
566
567         for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
568                 if(*ptr==UCS2_CHAR(c))
569                         count++;
570
571         SAFE_FREE(alloc_tmpbuf);
572         return(count);
573 }
574
575 /**
576  Safe string copy into a known length string. maxlength does not
577  include the terminating zero.
578 **/
579
580 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
581 {
582         size_t len;
583
584         if (!dest) {
585                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
586                 return NULL;
587         }
588
589 #ifdef DEVELOPER
590         clobber_region(fn,line,dest, maxlength+1);
591 #endif
592
593         if (!src) {
594                 *dest = 0;
595                 return dest;
596         }  
597
598         len = strnlen(src, maxlength+1);
599
600         if (len > maxlength) {
601                 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
602                          (unsigned long)(len-maxlength), (unsigned long)len, 
603                          (unsigned long)maxlength, src));
604                 len = maxlength;
605         }
606       
607         memmove(dest, src, len);
608         dest[len] = 0;
609         return dest;
610 }  
611
612 /**
613  Safe string cat into a string. maxlength does not
614  include the terminating zero.
615 **/
616 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
617 {
618         size_t src_len, dest_len;
619
620         if (!dest) {
621                 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
622                 return NULL;
623         }
624
625         if (!src)
626                 return dest;
627         
628         src_len = strnlen(src, maxlength + 1);
629         dest_len = strnlen(dest, maxlength + 1);
630
631 #ifdef DEVELOPER
632         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
633 #endif
634
635         if (src_len + dest_len > maxlength) {
636                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
637                          (int)(src_len + dest_len - maxlength), src));
638                 if (maxlength > dest_len) {
639                         memcpy(&dest[dest_len], src, maxlength - dest_len);
640                 }
641                 dest[maxlength] = 0;
642                 return NULL;
643         }
644
645         memcpy(&dest[dest_len], src, src_len);
646         dest[dest_len + src_len] = 0;
647         return dest;
648 }
649
650 /**
651  Paranoid strcpy into a buffer of given length (includes terminating
652  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
653  and replaces with '_'. Deliberately does *NOT* check for multibyte
654  characters. Don't change it !
655 **/
656 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
657 {
658         size_t len, i;
659
660 #ifdef DEVELOPER
661         clobber_region(fn, line, dest, maxlength);
662 #endif
663
664         if (!dest) {
665                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
666                 return NULL;
667         }
668
669         if (!src) {
670                 *dest = 0;
671                 return dest;
672         }  
673
674         len = strlen(src);
675         if (len >= maxlength)
676                 len = maxlength - 1;
677
678         if (!other_safe_chars)
679                 other_safe_chars = "";
680
681         for(i = 0; i < len; i++) {
682                 int val = (src[i] & 0xff);
683                 if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
684                         dest[i] = src[i];
685                 else
686                         dest[i] = '_';
687         }
688
689         dest[i] = '\0';
690
691         return dest;
692 }
693
694 /**
695  Like strncpy but always null terminates. Make sure there is room!
696  The variable n should always be one less than the available size.
697 **/
698 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
699 {
700         char *d = dest;
701
702 #ifdef DEVELOPER
703         clobber_region(fn, line, dest, n+1);
704 #endif
705
706         if (!dest) {
707                 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
708                 return(NULL);
709         }
710
711         if (!src) {
712                 *dest = 0;
713                 return(dest);
714         }
715         
716         while (n-- && (*d = *src)) {
717                 d++;
718                 src++;
719         }
720
721         *d = 0;
722         return(dest);
723 }
724
725 #if 0
726 /**
727  Like strncpy but copies up to the character marker.  always null terminates.
728  returns a pointer to the character marker in the source string (src).
729 **/
730
731 static char *strncpyn(char *dest, const char *src, size_t n, char c)
732 {
733         char *p;
734         size_t str_len;
735
736 #ifdef DEVELOPER
737         clobber_region(dest, n+1);
738 #endif
739         p = strchr_m(src, c);
740         if (p == NULL) {
741                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
742                 return NULL;
743         }
744
745         str_len = PTR_DIFF(p, src);
746         strncpy(dest, src, MIN(n, str_len));
747         dest[str_len] = '\0';
748
749         return p;
750 }
751 #endif
752
753 /**
754  Routine to get hex characters and turn them into a 16 byte array.
755  the array can be variable length, and any non-hex-numeric
756  characters are skipped.  "0xnn" or "0Xnn" is specially catered
757  for.
758
759  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
760
761 **/
762
763 size_t strhex_to_str(char *p, size_t len, const char *strhex)
764 {
765         size_t i;
766         size_t num_chars = 0;
767         unsigned char   lonybble, hinybble;
768         const char     *hexchars = "0123456789ABCDEF";
769         char           *p1 = NULL, *p2 = NULL;
770
771         for (i = 0; i < len && strhex[i] != 0; i++) {
772                 if (strnequal(hexchars, "0x", 2)) {
773                         i++; /* skip two chars */
774                         continue;
775                 }
776
777                 if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
778                         break;
779
780                 i++; /* next hex digit */
781
782                 if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
783                         break;
784
785                 /* get the two nybbles */
786                 hinybble = PTR_DIFF(p1, hexchars);
787                 lonybble = PTR_DIFF(p2, hexchars);
788
789                 p[num_chars] = (hinybble << 4) | lonybble;
790                 num_chars++;
791
792                 p1 = NULL;
793                 p2 = NULL;
794         }
795         return num_chars;
796 }
797
798 DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
799 {
800         DATA_BLOB ret_blob;
801
802         if (mem_ctx != NULL)
803                 ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
804         else
805                 ret_blob = data_blob(NULL, strlen(strhex)/2+1);
806
807         ret_blob.length = strhex_to_str((char*)ret_blob.data,   
808                                         strlen(strhex), 
809                                         strhex);
810
811         return ret_blob;
812 }
813
814 /**
815  * Routine to print a buffer as HEX digits, into an allocated string.
816  */
817
818 char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
819 {
820         int i;
821         char *hex_buffer;
822
823         hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
824
825         for (i = 0; i < len; i++)
826                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
827
828         return hex_buffer;
829 }
830
831 /**
832  Check if a string is part of a list.
833 **/
834
835 BOOL in_list(const char *s, const char *list, BOOL casesensitive)
836 {
837         pstring tok;
838         const char *p=list;
839
840         if (!list)
841                 return(False);
842
843         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
844                 if (casesensitive) {
845                         if (strcmp(tok,s) == 0)
846                                 return(True);
847                 } else {
848                         if (StrCaseCmp(tok,s) == 0)
849                                 return(True);
850                 }
851         }
852         return(False);
853 }
854
855 /* this is used to prevent lots of mallocs of size 1 */
856 static const char *null_string = "";
857
858 /**
859  Set a string value, allocing the space for the string
860 **/
861
862 static BOOL string_init(char **dest,const char *src)
863 {
864         size_t l;
865
866         if (!src)     
867                 src = "";
868
869         l = strlen(src);
870
871         if (l == 0) {
872                 *dest = CONST_DISCARD(char*, null_string);
873         } else {
874                 (*dest) = SMB_STRDUP(src);
875                 if ((*dest) == NULL) {
876                         DEBUG(0,("Out of memory in string_init\n"));
877                         return False;
878                 }
879         }
880         return(True);
881 }
882
883 /**
884  Free a string value.
885 **/
886
887 void string_free(char **s)
888 {
889         if (!s || !(*s))
890                 return;
891         if (*s == null_string)
892                 *s = NULL;
893         SAFE_FREE(*s);
894 }
895
896 /**
897  Set a string value, deallocating any existing space, and allocing the space
898  for the string
899 **/
900
901 BOOL string_set(char **dest,const char *src)
902 {
903         string_free(dest);
904         return(string_init(dest,src));
905 }
906
907 /**
908  Substitute a string for a pattern in another string. Make sure there is 
909  enough room!
910
911  This routine looks for pattern in s and replaces it with 
912  insert. It may do multiple replacements or just one.
913
914  Any of " ; ' $ or ` in the insert string are replaced with _
915  if len==0 then the string cannot be extended. This is different from the old
916  use of len==0 which was for no length checks to be done.
917 **/
918
919 void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
920                  BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
921 {
922         char *p;
923         ssize_t ls,lp,li, i;
924
925         if (!insert || !pattern || !*pattern || !s)
926                 return;
927
928         ls = (ssize_t)strlen(s);
929         lp = (ssize_t)strlen(pattern);
930         li = (ssize_t)strlen(insert);
931
932         if (len == 0)
933                 len = ls + 1; /* len is number of *bytes* */
934
935         while (lp <= ls && (p = strstr_m(s,pattern))) {
936                 if (ls + (li-lp) >= len) {
937                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
938                                  (int)(ls + (li-lp) - len),
939                                  pattern, (int)len));
940                         break;
941                 }
942                 if (li != lp) {
943                         memmove(p+li,p+lp,strlen(p+lp)+1);
944                 }
945                 for (i=0;i<li;i++) {
946                         switch (insert[i]) {
947                         case '`':
948                         case '"':
949                         case '\'':
950                         case ';':
951                         case '$':
952                                 /* allow a trailing $ (as in machine accounts) */
953                                 if (allow_trailing_dollar && (i == li - 1 )) {
954                                         p[i] = insert[i];
955                                         break;
956                                 }
957                         case '%':
958                         case '\r':
959                         case '\n':
960                                 if ( remove_unsafe_characters ) {
961                                         p[i] = '_';
962                                         /* yes this break should be here since we want to 
963                                            fall throw if not replacing unsafe chars */
964                                         break;
965                                 }
966                         default:
967                                 p[i] = insert[i];
968                         }
969                 }
970                 s = p + li;
971                 ls += (li-lp);
972
973                 if (replace_once)
974                         break;
975         }
976 }
977
978 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
979 {
980         string_sub2( s, pattern, insert, len, True, True, False );
981 }
982
983 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
984 {
985         string_sub2( s, pattern, insert, len, True, False, False );
986 }
987
988 void fstring_sub(char *s,const char *pattern,const char *insert)
989 {
990         string_sub(s, pattern, insert, sizeof(fstring));
991 }
992
993 void pstring_sub(char *s,const char *pattern,const char *insert)
994 {
995         string_sub(s, pattern, insert, sizeof(pstring));
996 }
997
998 /**
999  Similar to string_sub, but it will accept only allocated strings
1000  and may realloc them so pay attention at what you pass on no
1001  pointers inside strings, no pstrings or const may be passed
1002  as string.
1003 **/
1004
1005 char *realloc_string_sub(char *string, const char *pattern,
1006                          const char *insert)
1007 {
1008         char *p, *in;
1009         char *s;
1010         ssize_t ls,lp,li,ld, i;
1011
1012         if (!insert || !pattern || !*pattern || !string || !*string)
1013                 return NULL;
1014
1015         s = string;
1016
1017         in = SMB_STRDUP(insert);
1018         if (!in) {
1019                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1020                 return NULL;
1021         }
1022         ls = (ssize_t)strlen(s);
1023         lp = (ssize_t)strlen(pattern);
1024         li = (ssize_t)strlen(insert);
1025         ld = li - lp;
1026         for (i=0;i<li;i++) {
1027                 switch (in[i]) {
1028                         case '`':
1029                         case '"':
1030                         case '\'':
1031                         case ';':
1032                         case '$':
1033                         case '%':
1034                         case '\r':
1035                         case '\n':
1036                                 in[i] = '_';
1037                         default:
1038                                 /* ok */
1039                                 break;
1040                 }
1041         }
1042         
1043         while ((p = strstr_m(s,pattern))) {
1044                 if (ld > 0) {
1045                         int offset = PTR_DIFF(s,string);
1046                         string = SMB_REALLOC(string, ls + ld + 1);
1047                         if (!string) {
1048                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1049                                 SAFE_FREE(in);
1050                                 return NULL;
1051                         }
1052                         p = string + offset + (p - s);
1053                 }
1054                 if (li != lp) {
1055                         memmove(p+li,p+lp,strlen(p+lp)+1);
1056                 }
1057                 memcpy(p, in, li);
1058                 s = p + li;
1059                 ls += ld;
1060         }
1061         SAFE_FREE(in);
1062         return string;
1063 }
1064
1065 /* Same as string_sub, but returns a talloc'ed string */
1066
1067 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1068                         const char *pattern, const char *insert)
1069 {
1070         char *p, *in;
1071         char *s;
1072         char *string;
1073         ssize_t ls,lp,li,ld, i;
1074
1075         if (!insert || !pattern || !*pattern || !src || !*src)
1076                 return NULL;
1077
1078         string = talloc_strdup(mem_ctx, src);
1079         if (string == NULL) {
1080                 DEBUG(0, ("talloc_strdup failed\n"));
1081                 return NULL;
1082         }
1083
1084         s = string;
1085
1086         in = SMB_STRDUP(insert);
1087         if (!in) {
1088                 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1089                 return NULL;
1090         }
1091         ls = (ssize_t)strlen(s);
1092         lp = (ssize_t)strlen(pattern);
1093         li = (ssize_t)strlen(insert);
1094         ld = li - lp;
1095         for (i=0;i<li;i++) {
1096                 switch (in[i]) {
1097                         case '`':
1098                         case '"':
1099                         case '\'':
1100                         case ';':
1101                         case '$':
1102                         case '%':
1103                         case '\r':
1104                         case '\n':
1105                                 in[i] = '_';
1106                         default:
1107                                 /* ok */
1108                                 break;
1109                 }
1110         }
1111         
1112         while ((p = strstr_m(s,pattern))) {
1113                 if (ld > 0) {
1114                         int offset = PTR_DIFF(s,string);
1115                         string = TALLOC_REALLOC(mem_ctx, string, ls + ld + 1);
1116                         if (!string) {
1117                                 DEBUG(0, ("talloc_string_sub: out of "
1118                                           "memory!\n"));
1119                                 SAFE_FREE(in);
1120                                 return NULL;
1121                         }
1122                         p = string + offset + (p - s);
1123                 }
1124                 if (li != lp) {
1125                         memmove(p+li,p+lp,strlen(p+lp)+1);
1126                 }
1127                 memcpy(p, in, li);
1128                 s = p + li;
1129                 ls += ld;
1130         }
1131         SAFE_FREE(in);
1132         return string;
1133 }
1134
1135 /**
1136  Similar to string_sub() but allows for any character to be substituted. 
1137  Use with caution!
1138  if len==0 then the string cannot be extended. This is different from the old
1139  use of len==0 which was for no length checks to be done.
1140 **/
1141
1142 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1143 {
1144         char *p;
1145         ssize_t ls,lp,li;
1146
1147         if (!insert || !pattern || !s)
1148                 return;
1149
1150         ls = (ssize_t)strlen(s);
1151         lp = (ssize_t)strlen(pattern);
1152         li = (ssize_t)strlen(insert);
1153
1154         if (!*pattern)
1155                 return;
1156         
1157         if (len == 0)
1158                 len = ls + 1; /* len is number of *bytes* */
1159         
1160         while (lp <= ls && (p = strstr_m(s,pattern))) {
1161                 if (ls + (li-lp) >= len) {
1162                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1163                                  (int)(ls + (li-lp) - len),
1164                                  pattern, (int)len));
1165                         break;
1166                 }
1167                 if (li != lp) {
1168                         memmove(p+li,p+lp,strlen(p+lp)+1);
1169                 }
1170                 memcpy(p, insert, li);
1171                 s = p + li;
1172                 ls += (li-lp);
1173         }
1174 }
1175
1176 /**
1177  Similar to all_string_sub but for unicode strings.
1178  Return a new allocated unicode string.
1179  similar to string_sub() but allows for any character to be substituted.
1180  Use with caution!
1181 **/
1182
1183 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1184                                 const smb_ucs2_t *insert)
1185 {
1186         smb_ucs2_t *r, *rp;
1187         const smb_ucs2_t *sp;
1188         size_t  lr, lp, li, lt;
1189
1190         if (!insert || !pattern || !*pattern || !s)
1191                 return NULL;
1192
1193         lt = (size_t)strlen_w(s);
1194         lp = (size_t)strlen_w(pattern);
1195         li = (size_t)strlen_w(insert);
1196
1197         if (li > lp) {
1198                 const smb_ucs2_t *st = s;
1199                 int ld = li - lp;
1200                 while ((sp = strstr_w(st, pattern))) {
1201                         st = sp + lp;
1202                         lt += ld;
1203                 }
1204         }
1205
1206         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1207         if (!r) {
1208                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1209                 return NULL;
1210         }
1211
1212         while ((sp = strstr_w(s, pattern))) {
1213                 memcpy(rp, s, (sp - s));
1214                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1215                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1216                 s = sp + lp;
1217                 rp += li;
1218         }
1219         lr = ((rp - r) / sizeof(smb_ucs2_t));
1220         if (lr < lt) {
1221                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1222                 rp += (lt - lr);
1223         }
1224         *rp = 0;
1225
1226         return r;
1227 }
1228
1229 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1230                                              const char *insert)
1231 {
1232         wpstring p, i;
1233
1234         if (!insert || !pattern || !s)
1235                 return NULL;
1236         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1237         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1238         return all_string_sub_w(s, p, i);
1239 }
1240
1241 #if 0
1242 /**
1243  Splits out the front and back at a separator.
1244 **/
1245
1246 static void split_at_last_component(char *path, char *front, char sep, char *back)
1247 {
1248         char *p = strrchr_m(path, sep);
1249
1250         if (p != NULL)
1251                 *p = 0;
1252
1253         if (front != NULL)
1254                 pstrcpy(front, path);
1255
1256         if (p != NULL) {
1257                 if (back != NULL)
1258                         pstrcpy(back, p+1);
1259                 *p = '\\';
1260         } else {
1261                 if (back != NULL)
1262                         back[0] = 0;
1263         }
1264 }
1265 #endif
1266
1267 /**
1268  Write an octal as a string.
1269 **/
1270
1271 const char *octal_string(int i)
1272 {
1273         static char ret[64];
1274         if (i == -1)
1275                 return "-1";
1276         slprintf(ret, sizeof(ret)-1, "0%o", i);
1277         return ret;
1278 }
1279
1280
1281 /**
1282  Truncate a string at a specified length.
1283 **/
1284
1285 char *string_truncate(char *s, unsigned int length)
1286 {
1287         if (s && strlen(s) > length)
1288                 s[length] = 0;
1289         return s;
1290 }
1291
1292 /**
1293  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1294  We convert via ucs2 for now.
1295 **/
1296
1297 char *strchr_m(const char *src, char c)
1298 {
1299         wpstring ws;
1300         pstring s2;
1301         smb_ucs2_t *p;
1302         const char *s;
1303
1304         /* characters below 0x3F are guaranteed to not appear in
1305            non-initial position in multi-byte charsets */
1306         if ((c & 0xC0) == 0) {
1307                 return strchr(src, c);
1308         }
1309
1310         /* this is quite a common operation, so we want it to be
1311            fast. We optimise for the ascii case, knowing that all our
1312            supported multi-byte character sets are ascii-compatible
1313            (ie. they match for the first 128 chars) */
1314
1315         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1316                 if (*s == c)
1317                         return (char *)s;
1318         }
1319
1320         if (!*s)
1321                 return NULL;
1322
1323 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1324         /* With compose characters we must restart from the beginning. JRA. */
1325         s = src;
1326 #endif
1327
1328         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1329         p = strchr_w(ws, UCS2_CHAR(c));
1330         if (!p)
1331                 return NULL;
1332         *p = 0;
1333         pull_ucs2_pstring(s2, ws);
1334         return (char *)(s+strlen(s2));
1335 }
1336
1337 char *strrchr_m(const char *s, char c)
1338 {
1339         /* characters below 0x3F are guaranteed to not appear in
1340            non-initial position in multi-byte charsets */
1341         if ((c & 0xC0) == 0) {
1342                 return strrchr(s, c);
1343         }
1344
1345         /* this is quite a common operation, so we want it to be
1346            fast. We optimise for the ascii case, knowing that all our
1347            supported multi-byte character sets are ascii-compatible
1348            (ie. they match for the first 128 chars). Also, in Samba
1349            we only search for ascii characters in 'c' and that
1350            in all mb character sets with a compound character
1351            containing c, if 'c' is not a match at position
1352            p, then p[-1] > 0x7f. JRA. */
1353
1354         {
1355                 size_t len = strlen(s);
1356                 const char *cp = s;
1357                 BOOL got_mb = False;
1358
1359                 if (len == 0)
1360                         return NULL;
1361                 cp += (len - 1);
1362                 do {
1363                         if (c == *cp) {
1364                                 /* Could be a match. Part of a multibyte ? */
1365                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1366                                         /* Yep - go slow :-( */
1367                                         got_mb = True;
1368                                         break;
1369                                 }
1370                                 /* No - we have a match ! */
1371                                 return (char *)cp;
1372                         }
1373                 } while (cp-- != s);
1374                 if (!got_mb)
1375                         return NULL;
1376         }
1377
1378         /* String contained a non-ascii char. Slow path. */
1379         {
1380                 wpstring ws;
1381                 pstring s2;
1382                 smb_ucs2_t *p;
1383
1384                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1385                 p = strrchr_w(ws, UCS2_CHAR(c));
1386                 if (!p)
1387                         return NULL;
1388                 *p = 0;
1389                 pull_ucs2_pstring(s2, ws);
1390                 return (char *)(s+strlen(s2));
1391         }
1392 }
1393
1394 /***********************************************************************
1395  Return the equivalent of doing strrchr 'n' times - always going
1396  backwards.
1397 ***********************************************************************/
1398
1399 char *strnrchr_m(const char *s, char c, unsigned int n)
1400 {
1401         wpstring ws;
1402         pstring s2;
1403         smb_ucs2_t *p;
1404
1405         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1406         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1407         if (!p)
1408                 return NULL;
1409         *p = 0;
1410         pull_ucs2_pstring(s2, ws);
1411         return (char *)(s+strlen(s2));
1412 }
1413
1414 /***********************************************************************
1415  strstr_m - We convert via ucs2 for now.
1416 ***********************************************************************/
1417
1418 char *strstr_m(const char *src, const char *findstr)
1419 {
1420         smb_ucs2_t *p;
1421         smb_ucs2_t *src_w, *find_w;
1422         const char *s;
1423         char *s2;
1424         char *retp;
1425
1426         size_t findstr_len = 0;
1427
1428         /* for correctness */
1429         if (!findstr[0]) {
1430                 return (char*)src;
1431         }
1432
1433         /* Samba does single character findstr calls a *lot*. */
1434         if (findstr[1] == '\0')
1435                 return strchr_m(src, *findstr);
1436
1437         /* We optimise for the ascii case, knowing that all our
1438            supported multi-byte character sets are ascii-compatible
1439            (ie. they match for the first 128 chars) */
1440
1441         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1442                 if (*s == *findstr) {
1443                         if (!findstr_len) 
1444                                 findstr_len = strlen(findstr);
1445
1446                         if (strncmp(s, findstr, findstr_len) == 0) {
1447                                 return (char *)s;
1448                         }
1449                 }
1450         }
1451
1452         if (!*s)
1453                 return NULL;
1454
1455 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1456         /* 'make check' fails unless we do this */
1457
1458         /* With compose characters we must restart from the beginning. JRA. */
1459         s = src;
1460 #endif
1461
1462         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1463                 DEBUG(0,("strstr_m: src malloc fail\n"));
1464                 return NULL;
1465         }
1466         
1467         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1468                 SAFE_FREE(src_w);
1469                 DEBUG(0,("strstr_m: find malloc fail\n"));
1470                 return NULL;
1471         }
1472
1473         p = strstr_w(src_w, find_w);
1474
1475         if (!p) {
1476                 SAFE_FREE(src_w);
1477                 SAFE_FREE(find_w);
1478                 return NULL;
1479         }
1480         
1481         *p = 0;
1482         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1483                 SAFE_FREE(src_w);
1484                 SAFE_FREE(find_w);
1485                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1486                 return NULL;
1487         }
1488         retp = (char *)(s+strlen(s2));
1489         SAFE_FREE(src_w);
1490         SAFE_FREE(find_w);
1491         SAFE_FREE(s2);
1492         return retp;
1493 }
1494
1495 /**
1496  Convert a string to lower case.
1497 **/
1498
1499 void strlower_m(char *s)
1500 {
1501         size_t len;
1502         int errno_save;
1503
1504         /* this is quite a common operation, so we want it to be
1505            fast. We optimise for the ascii case, knowing that all our
1506            supported multi-byte character sets are ascii-compatible
1507            (ie. they match for the first 128 chars) */
1508
1509         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1510                 *s = tolower_ascii((unsigned char)*s);
1511                 s++;
1512         }
1513
1514         if (!*s)
1515                 return;
1516
1517         /* I assume that lowercased string takes the same number of bytes
1518          * as source string even in UTF-8 encoding. (VIV) */
1519         len = strlen(s) + 1;
1520         errno_save = errno;
1521         errno = 0;
1522         unix_strlower(s,len,s,len);     
1523         /* Catch mb conversion errors that may not terminate. */
1524         if (errno)
1525                 s[len-1] = '\0';
1526         errno = errno_save;
1527 }
1528
1529 /**
1530  Convert a string to upper case.
1531 **/
1532
1533 void strupper_m(char *s)
1534 {
1535         size_t len;
1536         int errno_save;
1537
1538         /* this is quite a common operation, so we want it to be
1539            fast. We optimise for the ascii case, knowing that all our
1540            supported multi-byte character sets are ascii-compatible
1541            (ie. they match for the first 128 chars) */
1542
1543         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1544                 *s = toupper_ascii((unsigned char)*s);
1545                 s++;
1546         }
1547
1548         if (!*s)
1549                 return;
1550
1551         /* I assume that lowercased string takes the same number of bytes
1552          * as source string even in multibyte encoding. (VIV) */
1553         len = strlen(s) + 1;
1554         errno_save = errno;
1555         errno = 0;
1556         unix_strupper(s,len,s,len);     
1557         /* Catch mb conversion errors that may not terminate. */
1558         if (errno)
1559                 s[len-1] = '\0';
1560         errno = errno_save;
1561 }
1562
1563 /**
1564  Return a RFC2254 binary string representation of a buffer.
1565  Used in LDAP filters.
1566  Caller must free.
1567 **/
1568
1569 char *binary_string_rfc2254(char *buf, int len)
1570 {
1571         char *s;
1572         int i, j;
1573         const char *hex = "0123456789ABCDEF";
1574         s = SMB_MALLOC(len * 3 + 1);
1575         if (!s)
1576                 return NULL;
1577         for (j=i=0;i<len;i++) {
1578                 s[j] = '\\';
1579                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1580                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1581                 j += 3;
1582         }
1583         s[j] = 0;
1584         return s;
1585 }
1586
1587 char *binary_string(char *buf, int len)
1588 {
1589         char *s;
1590         int i, j;
1591         const char *hex = "0123456789ABCDEF";
1592         s = SMB_MALLOC(len * 2 + 1);
1593         if (!s)
1594                 return NULL;
1595         for (j=i=0;i<len;i++) {
1596                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1597                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1598                 j += 2;
1599         }
1600         s[j] = 0;
1601         return s;
1602 }
1603 /**
1604  Just a typesafety wrapper for snprintf into a pstring.
1605 **/
1606
1607  int pstr_sprintf(pstring s, const char *fmt, ...)
1608 {
1609         va_list ap;
1610         int ret;
1611
1612         va_start(ap, fmt);
1613         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1614         va_end(ap);
1615         return ret;
1616 }
1617
1618
1619 /**
1620  Just a typesafety wrapper for snprintf into a fstring.
1621 **/
1622
1623 int fstr_sprintf(fstring s, const char *fmt, ...)
1624 {
1625         va_list ap;
1626         int ret;
1627
1628         va_start(ap, fmt);
1629         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1630         va_end(ap);
1631         return ret;
1632 }
1633
1634
1635 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1636 /**
1637  Some platforms don't have strndup.
1638 **/
1639 #if defined(PARANOID_MALLOC_CHECKER)
1640 #undef strndup
1641 #endif
1642
1643  char *strndup(const char *s, size_t n)
1644 {
1645         char *ret;
1646         
1647         n = strnlen(s, n);
1648         ret = SMB_MALLOC(n+1);
1649         if (!ret)
1650                 return NULL;
1651         memcpy(ret, s, n);
1652         ret[n] = 0;
1653
1654         return ret;
1655 }
1656
1657 #if defined(PARANOID_MALLOC_CHECKER)
1658 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1659 #endif
1660
1661 #endif
1662
1663 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1664 /**
1665  Some platforms don't have strnlen
1666 **/
1667
1668  size_t strnlen(const char *s, size_t n)
1669 {
1670         size_t i;
1671         for (i=0; i<n && s[i] != '\0'; i++)
1672                 /* noop */ ;
1673         return i;
1674 }
1675 #endif
1676
1677 /**
1678  List of Strings manipulation functions
1679 **/
1680
1681 #define S_LIST_ABS 16 /* List Allocation Block Size */
1682
1683 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1684 {
1685         char **list, **rlist;
1686         const char *str;
1687         char *s;
1688         int num, lsize;
1689         pstring tok;
1690         
1691         if (!string || !*string)
1692                 return NULL;
1693         if (mem_ctx) {
1694                 s = talloc_strdup(mem_ctx, string);
1695         } else {
1696                 s = SMB_STRDUP(string);
1697         }
1698         if (!s) {
1699                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1700                 return NULL;
1701         }
1702         if (!sep) sep = LIST_SEP;
1703         
1704         num = lsize = 0;
1705         list = NULL;
1706         
1707         str = s;
1708         while (next_token(&str, tok, sep, sizeof(tok))) {               
1709                 if (num == lsize) {
1710                         lsize += S_LIST_ABS;
1711                         if (mem_ctx) {
1712                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1713                         } else {
1714                                 /* We need to keep the old list on error so we can free the elements
1715                                    if the realloc fails. */
1716                                 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1717                         }
1718                         if (!rlist) {
1719                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1720                                 str_list_free(&list);
1721                                 if (mem_ctx) {
1722                                         TALLOC_FREE(s);
1723                                 } else {
1724                                         SAFE_FREE(s);
1725                                 }
1726                                 return NULL;
1727                         } else {
1728                                 list = rlist;
1729                         }
1730                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1731                 }
1732
1733                 if (mem_ctx) {
1734                         list[num] = talloc_strdup(mem_ctx, tok);
1735                 } else {
1736                         list[num] = SMB_STRDUP(tok);
1737                 }
1738                 
1739                 if (!list[num]) {
1740                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1741                         str_list_free(&list);
1742                         if (mem_ctx) {
1743                                 TALLOC_FREE(s);
1744                         } else {
1745                                 SAFE_FREE(s);
1746                         }
1747                         return NULL;
1748                 }
1749         
1750                 num++;  
1751         }
1752
1753         if (mem_ctx) {
1754                 TALLOC_FREE(s);
1755         } else {
1756                 SAFE_FREE(s);
1757         }
1758
1759         return list;
1760 }
1761
1762 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1763 {
1764         return str_list_make_internal(mem_ctx, string, sep);
1765 }
1766
1767 char **str_list_make(const char *string, const char *sep)
1768 {
1769         return str_list_make_internal(NULL, string, sep);
1770 }
1771
1772 BOOL str_list_copy(char ***dest, const char **src)
1773 {
1774         char **list, **rlist;
1775         int num, lsize;
1776         
1777         *dest = NULL;
1778         if (!src)
1779                 return False;
1780         
1781         num = lsize = 0;
1782         list = NULL;
1783                 
1784         while (src[num]) {
1785                 if (num == lsize) {
1786                         lsize += S_LIST_ABS;
1787                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1788                         if (!rlist) {
1789                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1790                                 str_list_free(&list);
1791                                 return False;
1792                         } else {
1793                                 list = rlist;
1794                         }
1795                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1796                 }
1797                 
1798                 list[num] = SMB_STRDUP(src[num]);
1799                 if (!list[num]) {
1800                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1801                         str_list_free(&list);
1802                         return False;
1803                 }
1804
1805                 num++;
1806         }
1807         
1808         *dest = list;
1809         return True;    
1810 }
1811
1812 /**
1813  * Return true if all the elements of the list match exactly.
1814  **/
1815 BOOL str_list_compare(char **list1, char **list2)
1816 {
1817         int num;
1818         
1819         if (!list1 || !list2)
1820                 return (list1 == list2); 
1821         
1822         for (num = 0; list1[num]; num++) {
1823                 if (!list2[num])
1824                         return False;
1825                 if (!strcsequal(list1[num], list2[num]))
1826                         return False;
1827         }
1828         if (list2[num])
1829                 return False; /* if list2 has more elements than list1 fail */
1830         
1831         return True;
1832 }
1833
1834 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1835 {
1836         char **tlist;
1837         
1838         if (!list || !*list)
1839                 return;
1840         tlist = *list;
1841         for(; *tlist; tlist++) {
1842                 if (mem_ctx) {
1843                         TALLOC_FREE(*tlist);
1844                 } else {
1845                         SAFE_FREE(*tlist);
1846                 }
1847         }
1848         if (mem_ctx) {
1849                 TALLOC_FREE(*tlist);
1850         } else {
1851                 SAFE_FREE(*list);
1852         }
1853 }
1854
1855 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1856 {
1857         str_list_free_internal(mem_ctx, list);
1858 }
1859
1860 void str_list_free(char ***list)
1861 {
1862         str_list_free_internal(NULL, list);
1863 }
1864
1865 /******************************************************************************
1866  *****************************************************************************/
1867
1868 int str_list_count( const char **list )
1869 {
1870         int i = 0;
1871
1872         if ( ! list )
1873                 return 0;
1874
1875         /* count the number of list members */
1876         
1877         for ( i=0; *list; i++, list++ );
1878         
1879         return i;
1880 }
1881
1882 /******************************************************************************
1883  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1884  for the work
1885  *****************************************************************************/
1886  
1887 BOOL str_list_sub_basic( char **list, const char *smb_name )
1888 {
1889         char *s, *tmpstr;
1890         
1891         while ( *list ) {
1892                 s = *list;
1893                 tmpstr = alloc_sub_basic(smb_name, s);
1894                 if ( !tmpstr ) {
1895                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1896                         return False;
1897                 }
1898
1899                 SAFE_FREE(*list);
1900                 *list = tmpstr;
1901                         
1902                 list++;
1903         }
1904
1905         return True;
1906 }
1907
1908 /******************************************************************************
1909  substritute a specific pattern in a string list
1910  *****************************************************************************/
1911  
1912 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1913 {
1914         char *p, *s, *t;
1915         ssize_t ls, lp, li, ld, i, d;
1916
1917         if (!list)
1918                 return False;
1919         if (!pattern)
1920                 return False;
1921         if (!insert)
1922                 return False;
1923
1924         lp = (ssize_t)strlen(pattern);
1925         li = (ssize_t)strlen(insert);
1926         ld = li -lp;
1927                         
1928         while (*list) {
1929                 s = *list;
1930                 ls = (ssize_t)strlen(s);
1931
1932                 while ((p = strstr_m(s, pattern))) {
1933                         t = *list;
1934                         d = p -t;
1935                         if (ld) {
1936                                 t = (char *) SMB_MALLOC(ls +ld +1);
1937                                 if (!t) {
1938                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1939                                         return False;
1940                                 }
1941                                 memcpy(t, *list, d);
1942                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1943                                 SAFE_FREE(*list);
1944                                 *list = t;
1945                                 ls += ld;
1946                                 s = t +d +li;
1947                         }
1948                         
1949                         for (i = 0; i < li; i++) {
1950                                 switch (insert[i]) {
1951                                         case '`':
1952                                         case '"':
1953                                         case '\'':
1954                                         case ';':
1955                                         case '$':
1956                                         case '%':
1957                                         case '\r':
1958                                         case '\n':
1959                                                 t[d +i] = '_';
1960                                                 break;
1961                                         default:
1962                                                 t[d +i] = insert[i];
1963                                 }
1964                         }       
1965                 }
1966                 
1967                 
1968                 list++;
1969         }
1970         
1971         return True;
1972 }
1973
1974
1975 #define IPSTR_LIST_SEP  ","
1976 #define IPSTR_LIST_CHAR ','
1977
1978 /**
1979  * Add ip string representation to ipstr list. Used also
1980  * as part of @function ipstr_list_make
1981  *
1982  * @param ipstr_list pointer to string containing ip list;
1983  *        MUST BE already allocated and IS reallocated if necessary
1984  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1985  *        as a result of reallocation)
1986  * @param ip IP address which is to be added to list
1987  * @return pointer to string appended with new ip and possibly
1988  *         reallocated to new length
1989  **/
1990
1991 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1992 {
1993         char* new_ipstr = NULL;
1994         
1995         /* arguments checking */
1996         if (!ipstr_list || !service) return NULL;
1997
1998         /* attempt to convert ip to a string and append colon separator to it */
1999         if (*ipstr_list) {
2000                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2001                         inet_ntoa(service->ip), service->port);
2002                 SAFE_FREE(*ipstr_list);
2003         } else {
2004                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2005         }
2006         *ipstr_list = new_ipstr;
2007         return *ipstr_list;
2008 }
2009
2010
2011 /**
2012  * Allocate and initialise an ipstr list using ip adresses
2013  * passed as arguments.
2014  *
2015  * @param ipstr_list pointer to string meant to be allocated and set
2016  * @param ip_list array of ip addresses to place in the list
2017  * @param ip_count number of addresses stored in ip_list
2018  * @return pointer to allocated ip string
2019  **/
2020  
2021 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2022 {
2023         int i;
2024         
2025         /* arguments checking */
2026         if (!ip_list && !ipstr_list) return 0;
2027
2028         *ipstr_list = NULL;
2029         
2030         /* process ip addresses given as arguments */
2031         for (i = 0; i < ip_count; i++)
2032                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2033         
2034         return (*ipstr_list);
2035 }
2036
2037
2038 /**
2039  * Parse given ip string list into array of ip addresses
2040  * (as ip_service structures)  
2041  *    e.g. 192.168.1.100:389,192.168.1.78, ...
2042  *
2043  * @param ipstr ip string list to be parsed 
2044  * @param ip_list pointer to array of ip addresses which is
2045  *        allocated by this function and must be freed by caller
2046  * @return number of succesfully parsed addresses
2047  **/
2048  
2049 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2050 {
2051         fstring token_str;
2052         size_t count;
2053         int i;
2054
2055         if (!ipstr_list || !ip_list) 
2056                 return 0;
2057         
2058         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2059         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2060                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2061                 return 0;
2062         }
2063         
2064         for ( i=0; 
2065                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
2066                 i++ ) 
2067         {
2068                 struct in_addr addr;
2069                 unsigned port = 0;      
2070                 char *p = strchr(token_str, ':');
2071                 
2072                 if (p) {
2073                         *p = 0;
2074                         port = atoi(p+1);
2075                 }
2076
2077                 /* convert single token to ip address */
2078                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2079                         break;
2080                                 
2081                 (*ip_list)[i].ip = addr;
2082                 (*ip_list)[i].port = port;
2083         }
2084         
2085         return count;
2086 }
2087
2088
2089 /**
2090  * Safely free ip string list
2091  *
2092  * @param ipstr_list ip string list to be freed
2093  **/
2094
2095 void ipstr_list_free(char* ipstr_list)
2096 {
2097         SAFE_FREE(ipstr_list);
2098 }
2099
2100
2101 /**
2102  Unescape a URL encoded string, in place.
2103 **/
2104
2105 void rfc1738_unescape(char *buf)
2106 {
2107         char *p=buf;
2108
2109         while (p && *p && (p=strchr_m(p,'%'))) {
2110                 int c1 = p[1];
2111                 int c2 = p[2];
2112
2113                 if (c1 >= '0' && c1 <= '9')
2114                         c1 = c1 - '0';
2115                 else if (c1 >= 'A' && c1 <= 'F')
2116                         c1 = 10 + c1 - 'A';
2117                 else if (c1 >= 'a' && c1 <= 'f')
2118                         c1 = 10 + c1 - 'a';
2119                 else {p++; continue;}
2120
2121                 if (c2 >= '0' && c2 <= '9')
2122                         c2 = c2 - '0';
2123                 else if (c2 >= 'A' && c2 <= 'F')
2124                         c2 = 10 + c2 - 'A';
2125                 else if (c2 >= 'a' && c2 <= 'f')
2126                         c2 = 10 + c2 - 'a';
2127                 else {p++; continue;}
2128                         
2129                 *p = (c1<<4) | c2;
2130
2131                 memmove(p+1, p+3, strlen(p+3)+1);
2132                 p++;
2133         }
2134 }
2135
2136 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2137
2138 /**
2139  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2140  **/
2141 DATA_BLOB base64_decode_data_blob(const char *s)
2142 {
2143         int bit_offset, byte_offset, idx, i, n;
2144         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2145         unsigned char *d = decoded.data;
2146         char *p;
2147
2148         n=i=0;
2149
2150         while (*s && (p=strchr_m(b64,*s))) {
2151                 idx = (int)(p - b64);
2152                 byte_offset = (i*6)/8;
2153                 bit_offset = (i*6)%8;
2154                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2155                 if (bit_offset < 3) {
2156                         d[byte_offset] |= (idx << (2-bit_offset));
2157                         n = byte_offset+1;
2158                 } else {
2159                         d[byte_offset] |= (idx >> (bit_offset-2));
2160                         d[byte_offset+1] = 0;
2161                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2162                         n = byte_offset+2;
2163                 }
2164                 s++; i++;
2165         }
2166
2167         if ((n > 0) && (*s == '=')) {
2168                 n -= 1;
2169         }
2170
2171         /* fix up length */
2172         decoded.length = n;
2173         return decoded;
2174 }
2175
2176 /**
2177  * Decode a base64 string in-place - wrapper for the above
2178  **/
2179 void base64_decode_inplace(char *s)
2180 {
2181         DATA_BLOB decoded = base64_decode_data_blob(s);
2182
2183         if ( decoded.length != 0 ) {
2184                 memcpy(s, decoded.data, decoded.length);
2185
2186                 /* null terminate */
2187                 s[decoded.length] = '\0';
2188         } else {
2189                 *s = '\0';
2190         }
2191
2192         data_blob_free(&decoded);
2193 }
2194
2195 /**
2196  * Encode a base64 string into a malloc()ed string caller to free.
2197  *
2198  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2199  **/
2200 char * base64_encode_data_blob(DATA_BLOB data)
2201 {
2202         int bits = 0;
2203         int char_count = 0;
2204         size_t out_cnt, len, output_len;
2205         char *result;
2206
2207         if (!data.length || !data.data)
2208                 return NULL;
2209
2210         out_cnt = 0;
2211         len = data.length;
2212         output_len = data.length * 2;
2213         result = SMB_MALLOC(output_len); /* get us plenty of space */
2214
2215         while (len-- && out_cnt < (data.length * 2) - 5) {
2216                 int c = (unsigned char) *(data.data++);
2217                 bits += c;
2218                 char_count++;
2219                 if (char_count == 3) {
2220                         result[out_cnt++] = b64[bits >> 18];
2221                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2222                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2223             result[out_cnt++] = b64[bits & 0x3f];
2224             bits = 0;
2225             char_count = 0;
2226         } else {
2227             bits <<= 8;
2228         }
2229     }
2230     if (char_count != 0) {
2231         bits <<= 16 - (8 * char_count);
2232         result[out_cnt++] = b64[bits >> 18];
2233         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2234         if (char_count == 1) {
2235             result[out_cnt++] = '=';
2236             result[out_cnt++] = '=';
2237         } else {
2238             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2239             result[out_cnt++] = '=';
2240         }
2241     }
2242     result[out_cnt] = '\0';     /* terminate */
2243     return result;
2244 }
2245
2246 /* read a SMB_BIG_UINT from a string */
2247 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2248 {
2249
2250         SMB_BIG_UINT val = -1;
2251         const char *p = nptr;
2252         
2253         while (p && *p && isspace(*p))
2254                 p++;
2255 #ifdef LARGE_SMB_OFF_T
2256         sscanf(p,"%llu",&val);  
2257 #else /* LARGE_SMB_OFF_T */
2258         sscanf(p,"%lu",&val);
2259 #endif /* LARGE_SMB_OFF_T */
2260         if (entptr) {
2261                 while (p && *p && isdigit(*p))
2262                         p++;
2263                 *entptr = p;
2264         }
2265
2266         return val;
2267 }
2268
2269 void string_append(char **left, const char *right)
2270 {
2271         int new_len = strlen(right) + 1;
2272
2273         if (*left == NULL) {
2274                 *left = SMB_MALLOC(new_len);
2275                 *left[0] = '\0';
2276         } else {
2277                 new_len += strlen(*left);
2278                 *left = SMB_REALLOC(*left, new_len);
2279         }
2280
2281         if (*left == NULL) {
2282                 return;
2283         }
2284
2285         safe_strcat(*left, right, new_len-1);
2286 }
2287
2288 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2289                          const char *str, const char ***strings,
2290                          int *num)
2291 {
2292         char *dup_str = talloc_strdup(mem_ctx, str);
2293
2294         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2295
2296         if ((*strings == NULL) || (dup_str == NULL))
2297                 return False;
2298
2299         (*strings)[*num] = dup_str;
2300         *num += 1;
2301         return True;
2302 }
2303
2304 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2305  * error checking in between. The indiation that something weird happened is
2306  * string==NULL */
2307
2308 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2309                     size_t *bufsize, const char *fmt, ...)
2310 {
2311         va_list ap;
2312         char *newstr;
2313         int ret;
2314         BOOL increased;
2315
2316         /* len<0 is an internal marker that something failed */
2317         if (*len < 0)
2318                 goto error;
2319
2320         if (*string == NULL) {
2321                 if (*bufsize == 0)
2322                         *bufsize = 128;
2323
2324                 if (mem_ctx != NULL)
2325                         *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2326                 else
2327                         *string = SMB_MALLOC_ARRAY(char, *bufsize);
2328
2329                 if (*string == NULL)
2330                         goto error;
2331         }
2332
2333         va_start(ap, fmt);
2334         ret = vasprintf(&newstr, fmt, ap);
2335         va_end(ap);
2336
2337         if (ret < 0)
2338                 goto error;
2339
2340         increased = False;
2341
2342         while ((*len)+ret >= *bufsize) {
2343                 increased = True;
2344                 *bufsize *= 2;
2345                 if (*bufsize >= (1024*1024*256))
2346                         goto error;
2347         }
2348
2349         if (increased) {
2350                 if (mem_ctx != NULL) {
2351                         *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2352                                                        *bufsize);
2353                 } else {
2354                         *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2355                 }
2356
2357                 if (*string == NULL) {
2358                         goto error;
2359                 }
2360         }
2361
2362         StrnCpy((*string)+(*len), newstr, ret);
2363         (*len) += ret;
2364         free(newstr);
2365         return;
2366
2367  error:
2368         *len = -1;
2369         *string = NULL;
2370 }
2371
2372 /*
2373    Returns the substring from src between the first occurrence of
2374    the char "front" and the first occurence of the char "back".
2375    Mallocs the return string which must be freed.  Not for use
2376    with wide character strings.
2377 */
2378 char *sstring_sub(const char *src, char front, char back)
2379 {
2380         char *temp1, *temp2, *temp3;
2381         ptrdiff_t len;
2382
2383         temp1 = strchr(src, front);
2384         if (temp1 == NULL) return NULL;
2385         temp2 = strchr(src, back);
2386         if (temp2 == NULL) return NULL;
2387         len = temp2 - temp1;
2388         if (len <= 0) return NULL;
2389         temp3 = (char*)SMB_MALLOC(len);
2390         if (temp3 == NULL) {
2391                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2392                 return NULL;
2393         }
2394         memcpy(temp3, temp1+1, len-1);
2395         temp3[len-1] = '\0';
2396         return temp3;
2397 }
2398
2399 /********************************************************************
2400  Check a string for any occurrences of a specified list of invalid
2401  characters.
2402 ********************************************************************/
2403
2404 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2405 {
2406         int i;
2407
2408         for ( i=0; i<max_len && name[i]; i++ ) {
2409                 /* fail if strchr_m() finds one of the invalid characters */
2410                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2411                         return False;
2412                 }
2413         }
2414
2415         return True;
2416 }
2417