r13915: Fixed a very interesting class of realloc() bugs found by Coverity.
[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 char *null_string = NULL;
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         if (!src)     
866                 src = "";
867
868         l = strlen(src);
869
870         if (l == 0) {
871                 if (!null_string) {
872                         if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
873                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
874                                 return False;
875                         }
876                         *null_string = 0;
877                 }
878                 *dest = null_string;
879         } else {
880                 (*dest) = SMB_STRDUP(src);
881                 if ((*dest) == NULL) {
882                         DEBUG(0,("Out of memory in string_init\n"));
883                         return False;
884                 }
885         }
886         return(True);
887 }
888
889 /**
890  Free a string value.
891 **/
892
893 void string_free(char **s)
894 {
895         if (!s || !(*s))
896                 return;
897         if (*s == null_string)
898                 *s = NULL;
899         SAFE_FREE(*s);
900 }
901
902 /**
903  Set a string value, deallocating any existing space, and allocing the space
904  for the string
905 **/
906
907 BOOL string_set(char **dest,const char *src)
908 {
909         string_free(dest);
910         return(string_init(dest,src));
911 }
912
913 /**
914  Substitute a string for a pattern in another string. Make sure there is 
915  enough room!
916
917  This routine looks for pattern in s and replaces it with 
918  insert. It may do multiple replacements or just one.
919
920  Any of " ; ' $ or ` in the insert string are replaced with _
921  if len==0 then the string cannot be extended. This is different from the old
922  use of len==0 which was for no length checks to be done.
923 **/
924
925 void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
926                  BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
927 {
928         char *p;
929         ssize_t ls,lp,li, i;
930
931         if (!insert || !pattern || !*pattern || !s)
932                 return;
933
934         ls = (ssize_t)strlen(s);
935         lp = (ssize_t)strlen(pattern);
936         li = (ssize_t)strlen(insert);
937
938         if (len == 0)
939                 len = ls + 1; /* len is number of *bytes* */
940
941         while (lp <= ls && (p = strstr_m(s,pattern))) {
942                 if (ls + (li-lp) >= len) {
943                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
944                                  (int)(ls + (li-lp) - len),
945                                  pattern, (int)len));
946                         break;
947                 }
948                 if (li != lp) {
949                         memmove(p+li,p+lp,strlen(p+lp)+1);
950                 }
951                 for (i=0;i<li;i++) {
952                         switch (insert[i]) {
953                         case '`':
954                         case '"':
955                         case '\'':
956                         case ';':
957                         case '$':
958                                 /* allow a trailing $ (as in machine accounts) */
959                                 if (allow_trailing_dollar && (i == li - 1 )) {
960                                         p[i] = insert[i];
961                                         break;
962                                 }
963                         case '%':
964                         case '\r':
965                         case '\n':
966                                 if ( remove_unsafe_characters ) {
967                                         p[i] = '_';
968                                         /* yes this break should be here since we want to 
969                                            fall throw if not replacing unsafe chars */
970                                         break;
971                                 }
972                         default:
973                                 p[i] = insert[i];
974                         }
975                 }
976                 s = p + li;
977                 ls += (li-lp);
978
979                 if (replace_once)
980                         break;
981         }
982 }
983
984 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
985 {
986         string_sub2( s, pattern, insert, len, True, True, False );
987 }
988
989 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
990 {
991         string_sub2( s, pattern, insert, len, True, False, False );
992 }
993
994 void fstring_sub(char *s,const char *pattern,const char *insert)
995 {
996         string_sub(s, pattern, insert, sizeof(fstring));
997 }
998
999 void pstring_sub(char *s,const char *pattern,const char *insert)
1000 {
1001         string_sub(s, pattern, insert, sizeof(pstring));
1002 }
1003
1004 /**
1005  Similar to string_sub, but it will accept only allocated strings
1006  and may realloc them so pay attention at what you pass on no
1007  pointers inside strings, no pstrings or const may be passed
1008  as string.
1009 **/
1010
1011 char *realloc_string_sub(char *string, const char *pattern,
1012                          const char *insert)
1013 {
1014         char *p, *in;
1015         char *s;
1016         ssize_t ls,lp,li,ld, i;
1017
1018         if (!insert || !pattern || !*pattern || !string || !*string)
1019                 return NULL;
1020
1021         s = string;
1022
1023         in = SMB_STRDUP(insert);
1024         if (!in) {
1025                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1026                 return NULL;
1027         }
1028         ls = (ssize_t)strlen(s);
1029         lp = (ssize_t)strlen(pattern);
1030         li = (ssize_t)strlen(insert);
1031         ld = li - lp;
1032         for (i=0;i<li;i++) {
1033                 switch (in[i]) {
1034                         case '`':
1035                         case '"':
1036                         case '\'':
1037                         case ';':
1038                         case '$':
1039                         case '%':
1040                         case '\r':
1041                         case '\n':
1042                                 in[i] = '_';
1043                         default:
1044                                 /* ok */
1045                                 break;
1046                 }
1047         }
1048         
1049         while ((p = strstr_m(s,pattern))) {
1050                 if (ld > 0) {
1051                         int offset = PTR_DIFF(s,string);
1052                         string = SMB_REALLOC(string, ls + ld + 1);
1053                         if (!string) {
1054                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1055                                 SAFE_FREE(in);
1056                                 return NULL;
1057                         }
1058                         p = string + offset + (p - s);
1059                 }
1060                 if (li != lp) {
1061                         memmove(p+li,p+lp,strlen(p+lp)+1);
1062                 }
1063                 memcpy(p, in, li);
1064                 s = p + li;
1065                 ls += ld;
1066         }
1067         SAFE_FREE(in);
1068         return string;
1069 }
1070
1071 /* Same as string_sub, but returns a talloc'ed string */
1072
1073 char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
1074                         const char *pattern, const char *insert)
1075 {
1076         char *p, *in;
1077         char *s;
1078         char *string;
1079         ssize_t ls,lp,li,ld, i;
1080
1081         if (!insert || !pattern || !*pattern || !src || !*src)
1082                 return NULL;
1083
1084         string = talloc_strdup(mem_ctx, src);
1085         if (string == NULL) {
1086                 DEBUG(0, ("talloc_strdup failed\n"));
1087                 return NULL;
1088         }
1089
1090         s = string;
1091
1092         in = SMB_STRDUP(insert);
1093         if (!in) {
1094                 DEBUG(0, ("talloc_string_sub: out of memory!\n"));
1095                 return NULL;
1096         }
1097         ls = (ssize_t)strlen(s);
1098         lp = (ssize_t)strlen(pattern);
1099         li = (ssize_t)strlen(insert);
1100         ld = li - lp;
1101         for (i=0;i<li;i++) {
1102                 switch (in[i]) {
1103                         case '`':
1104                         case '"':
1105                         case '\'':
1106                         case ';':
1107                         case '$':
1108                         case '%':
1109                         case '\r':
1110                         case '\n':
1111                                 in[i] = '_';
1112                         default:
1113                                 /* ok */
1114                                 break;
1115                 }
1116         }
1117         
1118         while ((p = strstr_m(s,pattern))) {
1119                 if (ld > 0) {
1120                         int offset = PTR_DIFF(s,string);
1121                         string = TALLOC_REALLOC(mem_ctx, string, ls + ld + 1);
1122                         if (!string) {
1123                                 DEBUG(0, ("talloc_string_sub: out of "
1124                                           "memory!\n"));
1125                                 SAFE_FREE(in);
1126                                 return NULL;
1127                         }
1128                         p = string + offset + (p - s);
1129                 }
1130                 if (li != lp) {
1131                         memmove(p+li,p+lp,strlen(p+lp)+1);
1132                 }
1133                 memcpy(p, in, li);
1134                 s = p + li;
1135                 ls += ld;
1136         }
1137         SAFE_FREE(in);
1138         return string;
1139 }
1140
1141 /**
1142  Similar to string_sub() but allows for any character to be substituted. 
1143  Use with caution!
1144  if len==0 then the string cannot be extended. This is different from the old
1145  use of len==0 which was for no length checks to be done.
1146 **/
1147
1148 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1149 {
1150         char *p;
1151         ssize_t ls,lp,li;
1152
1153         if (!insert || !pattern || !s)
1154                 return;
1155
1156         ls = (ssize_t)strlen(s);
1157         lp = (ssize_t)strlen(pattern);
1158         li = (ssize_t)strlen(insert);
1159
1160         if (!*pattern)
1161                 return;
1162         
1163         if (len == 0)
1164                 len = ls + 1; /* len is number of *bytes* */
1165         
1166         while (lp <= ls && (p = strstr_m(s,pattern))) {
1167                 if (ls + (li-lp) >= len) {
1168                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1169                                  (int)(ls + (li-lp) - len),
1170                                  pattern, (int)len));
1171                         break;
1172                 }
1173                 if (li != lp) {
1174                         memmove(p+li,p+lp,strlen(p+lp)+1);
1175                 }
1176                 memcpy(p, insert, li);
1177                 s = p + li;
1178                 ls += (li-lp);
1179         }
1180 }
1181
1182 /**
1183  Similar to all_string_sub but for unicode strings.
1184  Return a new allocated unicode string.
1185  similar to string_sub() but allows for any character to be substituted.
1186  Use with caution!
1187 **/
1188
1189 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1190                                 const smb_ucs2_t *insert)
1191 {
1192         smb_ucs2_t *r, *rp;
1193         const smb_ucs2_t *sp;
1194         size_t  lr, lp, li, lt;
1195
1196         if (!insert || !pattern || !*pattern || !s)
1197                 return NULL;
1198
1199         lt = (size_t)strlen_w(s);
1200         lp = (size_t)strlen_w(pattern);
1201         li = (size_t)strlen_w(insert);
1202
1203         if (li > lp) {
1204                 const smb_ucs2_t *st = s;
1205                 int ld = li - lp;
1206                 while ((sp = strstr_w(st, pattern))) {
1207                         st = sp + lp;
1208                         lt += ld;
1209                 }
1210         }
1211
1212         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1213         if (!r) {
1214                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1215                 return NULL;
1216         }
1217
1218         while ((sp = strstr_w(s, pattern))) {
1219                 memcpy(rp, s, (sp - s));
1220                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1221                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1222                 s = sp + lp;
1223                 rp += li;
1224         }
1225         lr = ((rp - r) / sizeof(smb_ucs2_t));
1226         if (lr < lt) {
1227                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1228                 rp += (lt - lr);
1229         }
1230         *rp = 0;
1231
1232         return r;
1233 }
1234
1235 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1236                                              const char *insert)
1237 {
1238         wpstring p, i;
1239
1240         if (!insert || !pattern || !s)
1241                 return NULL;
1242         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1243         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1244         return all_string_sub_w(s, p, i);
1245 }
1246
1247 #if 0
1248 /**
1249  Splits out the front and back at a separator.
1250 **/
1251
1252 static void split_at_last_component(char *path, char *front, char sep, char *back)
1253 {
1254         char *p = strrchr_m(path, sep);
1255
1256         if (p != NULL)
1257                 *p = 0;
1258
1259         if (front != NULL)
1260                 pstrcpy(front, path);
1261
1262         if (p != NULL) {
1263                 if (back != NULL)
1264                         pstrcpy(back, p+1);
1265                 *p = '\\';
1266         } else {
1267                 if (back != NULL)
1268                         back[0] = 0;
1269         }
1270 }
1271 #endif
1272
1273 /**
1274  Write an octal as a string.
1275 **/
1276
1277 const char *octal_string(int i)
1278 {
1279         static char ret[64];
1280         if (i == -1)
1281                 return "-1";
1282         slprintf(ret, sizeof(ret)-1, "0%o", i);
1283         return ret;
1284 }
1285
1286
1287 /**
1288  Truncate a string at a specified length.
1289 **/
1290
1291 char *string_truncate(char *s, unsigned int length)
1292 {
1293         if (s && strlen(s) > length)
1294                 s[length] = 0;
1295         return s;
1296 }
1297
1298 /**
1299  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1300  We convert via ucs2 for now.
1301 **/
1302
1303 char *strchr_m(const char *src, char c)
1304 {
1305         wpstring ws;
1306         pstring s2;
1307         smb_ucs2_t *p;
1308         const char *s;
1309
1310         /* characters below 0x3F are guaranteed to not appear in
1311            non-initial position in multi-byte charsets */
1312         if ((c & 0xC0) == 0) {
1313                 return strchr(src, c);
1314         }
1315
1316         /* this is quite a common operation, so we want it to be
1317            fast. We optimise for the ascii case, knowing that all our
1318            supported multi-byte character sets are ascii-compatible
1319            (ie. they match for the first 128 chars) */
1320
1321         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1322                 if (*s == c)
1323                         return (char *)s;
1324         }
1325
1326         if (!*s)
1327                 return NULL;
1328
1329 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1330         /* With compose characters we must restart from the beginning. JRA. */
1331         s = src;
1332 #endif
1333
1334         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1335         p = strchr_w(ws, UCS2_CHAR(c));
1336         if (!p)
1337                 return NULL;
1338         *p = 0;
1339         pull_ucs2_pstring(s2, ws);
1340         return (char *)(s+strlen(s2));
1341 }
1342
1343 char *strrchr_m(const char *s, char c)
1344 {
1345         /* characters below 0x3F are guaranteed to not appear in
1346            non-initial position in multi-byte charsets */
1347         if ((c & 0xC0) == 0) {
1348                 return strrchr(s, c);
1349         }
1350
1351         /* this is quite a common operation, so we want it to be
1352            fast. We optimise for the ascii case, knowing that all our
1353            supported multi-byte character sets are ascii-compatible
1354            (ie. they match for the first 128 chars). Also, in Samba
1355            we only search for ascii characters in 'c' and that
1356            in all mb character sets with a compound character
1357            containing c, if 'c' is not a match at position
1358            p, then p[-1] > 0x7f. JRA. */
1359
1360         {
1361                 size_t len = strlen(s);
1362                 const char *cp = s;
1363                 BOOL got_mb = False;
1364
1365                 if (len == 0)
1366                         return NULL;
1367                 cp += (len - 1);
1368                 do {
1369                         if (c == *cp) {
1370                                 /* Could be a match. Part of a multibyte ? */
1371                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1372                                         /* Yep - go slow :-( */
1373                                         got_mb = True;
1374                                         break;
1375                                 }
1376                                 /* No - we have a match ! */
1377                                 return (char *)cp;
1378                         }
1379                 } while (cp-- != s);
1380                 if (!got_mb)
1381                         return NULL;
1382         }
1383
1384         /* String contained a non-ascii char. Slow path. */
1385         {
1386                 wpstring ws;
1387                 pstring s2;
1388                 smb_ucs2_t *p;
1389
1390                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1391                 p = strrchr_w(ws, UCS2_CHAR(c));
1392                 if (!p)
1393                         return NULL;
1394                 *p = 0;
1395                 pull_ucs2_pstring(s2, ws);
1396                 return (char *)(s+strlen(s2));
1397         }
1398 }
1399
1400 /***********************************************************************
1401  Return the equivalent of doing strrchr 'n' times - always going
1402  backwards.
1403 ***********************************************************************/
1404
1405 char *strnrchr_m(const char *s, char c, unsigned int n)
1406 {
1407         wpstring ws;
1408         pstring s2;
1409         smb_ucs2_t *p;
1410
1411         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1412         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1413         if (!p)
1414                 return NULL;
1415         *p = 0;
1416         pull_ucs2_pstring(s2, ws);
1417         return (char *)(s+strlen(s2));
1418 }
1419
1420 /***********************************************************************
1421  strstr_m - We convert via ucs2 for now.
1422 ***********************************************************************/
1423
1424 char *strstr_m(const char *src, const char *findstr)
1425 {
1426         smb_ucs2_t *p;
1427         smb_ucs2_t *src_w, *find_w;
1428         const char *s;
1429         char *s2;
1430         char *retp;
1431
1432         size_t findstr_len = 0;
1433
1434         /* for correctness */
1435         if (!findstr[0]) {
1436                 return (char*)src;
1437         }
1438
1439         /* Samba does single character findstr calls a *lot*. */
1440         if (findstr[1] == '\0')
1441                 return strchr_m(src, *findstr);
1442
1443         /* We optimise for the ascii case, knowing that all our
1444            supported multi-byte character sets are ascii-compatible
1445            (ie. they match for the first 128 chars) */
1446
1447         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1448                 if (*s == *findstr) {
1449                         if (!findstr_len) 
1450                                 findstr_len = strlen(findstr);
1451
1452                         if (strncmp(s, findstr, findstr_len) == 0) {
1453                                 return (char *)s;
1454                         }
1455                 }
1456         }
1457
1458         if (!*s)
1459                 return NULL;
1460
1461 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1462         /* 'make check' fails unless we do this */
1463
1464         /* With compose characters we must restart from the beginning. JRA. */
1465         s = src;
1466 #endif
1467
1468         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1469                 DEBUG(0,("strstr_m: src malloc fail\n"));
1470                 return NULL;
1471         }
1472         
1473         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1474                 SAFE_FREE(src_w);
1475                 DEBUG(0,("strstr_m: find malloc fail\n"));
1476                 return NULL;
1477         }
1478
1479         p = strstr_w(src_w, find_w);
1480
1481         if (!p) {
1482                 SAFE_FREE(src_w);
1483                 SAFE_FREE(find_w);
1484                 return NULL;
1485         }
1486         
1487         *p = 0;
1488         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1489                 SAFE_FREE(src_w);
1490                 SAFE_FREE(find_w);
1491                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1492                 return NULL;
1493         }
1494         retp = (char *)(s+strlen(s2));
1495         SAFE_FREE(src_w);
1496         SAFE_FREE(find_w);
1497         SAFE_FREE(s2);
1498         return retp;
1499 }
1500
1501 /**
1502  Convert a string to lower case.
1503 **/
1504
1505 void strlower_m(char *s)
1506 {
1507         size_t len;
1508         int errno_save;
1509
1510         /* this is quite a common operation, so we want it to be
1511            fast. We optimise for the ascii case, knowing that all our
1512            supported multi-byte character sets are ascii-compatible
1513            (ie. they match for the first 128 chars) */
1514
1515         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1516                 *s = tolower_ascii((unsigned char)*s);
1517                 s++;
1518         }
1519
1520         if (!*s)
1521                 return;
1522
1523         /* I assume that lowercased string takes the same number of bytes
1524          * as source string even in UTF-8 encoding. (VIV) */
1525         len = strlen(s) + 1;
1526         errno_save = errno;
1527         errno = 0;
1528         unix_strlower(s,len,s,len);     
1529         /* Catch mb conversion errors that may not terminate. */
1530         if (errno)
1531                 s[len-1] = '\0';
1532         errno = errno_save;
1533 }
1534
1535 /**
1536  Convert a string to upper case.
1537 **/
1538
1539 void strupper_m(char *s)
1540 {
1541         size_t len;
1542         int errno_save;
1543
1544         /* this is quite a common operation, so we want it to be
1545            fast. We optimise for the ascii case, knowing that all our
1546            supported multi-byte character sets are ascii-compatible
1547            (ie. they match for the first 128 chars) */
1548
1549         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1550                 *s = toupper_ascii((unsigned char)*s);
1551                 s++;
1552         }
1553
1554         if (!*s)
1555                 return;
1556
1557         /* I assume that lowercased string takes the same number of bytes
1558          * as source string even in multibyte encoding. (VIV) */
1559         len = strlen(s) + 1;
1560         errno_save = errno;
1561         errno = 0;
1562         unix_strupper(s,len,s,len);     
1563         /* Catch mb conversion errors that may not terminate. */
1564         if (errno)
1565                 s[len-1] = '\0';
1566         errno = errno_save;
1567 }
1568
1569 /**
1570  Return a RFC2254 binary string representation of a buffer.
1571  Used in LDAP filters.
1572  Caller must free.
1573 **/
1574
1575 char *binary_string(char *buf, int len)
1576 {
1577         char *s;
1578         int i, j;
1579         const char *hex = "0123456789ABCDEF";
1580         s = SMB_MALLOC(len * 3 + 1);
1581         if (!s)
1582                 return NULL;
1583         for (j=i=0;i<len;i++) {
1584                 s[j] = '\\';
1585                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1586                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1587                 j += 3;
1588         }
1589         s[j] = 0;
1590         return s;
1591 }
1592
1593 /**
1594  Just a typesafety wrapper for snprintf into a pstring.
1595 **/
1596
1597  int pstr_sprintf(pstring s, const char *fmt, ...)
1598 {
1599         va_list ap;
1600         int ret;
1601
1602         va_start(ap, fmt);
1603         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1604         va_end(ap);
1605         return ret;
1606 }
1607
1608
1609 /**
1610  Just a typesafety wrapper for snprintf into a fstring.
1611 **/
1612
1613 int fstr_sprintf(fstring s, const char *fmt, ...)
1614 {
1615         va_list ap;
1616         int ret;
1617
1618         va_start(ap, fmt);
1619         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1620         va_end(ap);
1621         return ret;
1622 }
1623
1624
1625 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1626 /**
1627  Some platforms don't have strndup.
1628 **/
1629 #if defined(PARANOID_MALLOC_CHECKER)
1630 #undef strndup
1631 #endif
1632
1633  char *strndup(const char *s, size_t n)
1634 {
1635         char *ret;
1636         
1637         n = strnlen(s, n);
1638         ret = SMB_MALLOC(n+1);
1639         if (!ret)
1640                 return NULL;
1641         memcpy(ret, s, n);
1642         ret[n] = 0;
1643
1644         return ret;
1645 }
1646
1647 #if defined(PARANOID_MALLOC_CHECKER)
1648 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1649 #endif
1650
1651 #endif
1652
1653 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1654 /**
1655  Some platforms don't have strnlen
1656 **/
1657
1658  size_t strnlen(const char *s, size_t n)
1659 {
1660         size_t i;
1661         for (i=0; i<n && s[i] != '\0'; i++)
1662                 /* noop */ ;
1663         return i;
1664 }
1665 #endif
1666
1667 /**
1668  List of Strings manipulation functions
1669 **/
1670
1671 #define S_LIST_ABS 16 /* List Allocation Block Size */
1672
1673 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1674 {
1675         char **list, **rlist;
1676         const char *str;
1677         char *s;
1678         int num, lsize;
1679         pstring tok;
1680         
1681         if (!string || !*string)
1682                 return NULL;
1683         if (mem_ctx) {
1684                 s = talloc_strdup(mem_ctx, string);
1685         } else {
1686                 s = SMB_STRDUP(string);
1687         }
1688         if (!s) {
1689                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1690                 return NULL;
1691         }
1692         if (!sep) sep = LIST_SEP;
1693         
1694         num = lsize = 0;
1695         list = NULL;
1696         
1697         str = s;
1698         while (next_token(&str, tok, sep, sizeof(tok))) {               
1699                 if (num == lsize) {
1700                         lsize += S_LIST_ABS;
1701                         if (mem_ctx) {
1702                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1703                         } else {
1704                                 /* We need to keep the old list on error so we can free the elements
1705                                    if the realloc fails. */
1706                                 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1707                         }
1708                         if (!rlist) {
1709                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1710                                 str_list_free(&list);
1711                                 if (mem_ctx) {
1712                                         TALLOC_FREE(s);
1713                                 } else {
1714                                         SAFE_FREE(s);
1715                                 }
1716                                 return NULL;
1717                         } else {
1718                                 list = rlist;
1719                         }
1720                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1721                 }
1722
1723                 if (mem_ctx) {
1724                         list[num] = talloc_strdup(mem_ctx, tok);
1725                 } else {
1726                         list[num] = SMB_STRDUP(tok);
1727                 }
1728                 
1729                 if (!list[num]) {
1730                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1731                         str_list_free(&list);
1732                         if (mem_ctx) {
1733                                 TALLOC_FREE(s);
1734                         } else {
1735                                 SAFE_FREE(s);
1736                         }
1737                         return NULL;
1738                 }
1739         
1740                 num++;  
1741         }
1742
1743         if (mem_ctx) {
1744                 TALLOC_FREE(s);
1745         } else {
1746                 SAFE_FREE(s);
1747         }
1748
1749         return list;
1750 }
1751
1752 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1753 {
1754         return str_list_make_internal(mem_ctx, string, sep);
1755 }
1756
1757 char **str_list_make(const char *string, const char *sep)
1758 {
1759         return str_list_make_internal(NULL, string, sep);
1760 }
1761
1762 BOOL str_list_copy(char ***dest, const char **src)
1763 {
1764         char **list, **rlist;
1765         int num, lsize;
1766         
1767         *dest = NULL;
1768         if (!src)
1769                 return False;
1770         
1771         num = lsize = 0;
1772         list = NULL;
1773                 
1774         while (src[num]) {
1775                 if (num == lsize) {
1776                         lsize += S_LIST_ABS;
1777                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1778                         if (!rlist) {
1779                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1780                                 str_list_free(&list);
1781                                 return False;
1782                         } else
1783                                 list = rlist;
1784                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1785                 }
1786                 
1787                 list[num] = SMB_STRDUP(src[num]);
1788                 if (!list[num]) {
1789                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1790                         str_list_free(&list);
1791                         return False;
1792                 }
1793
1794                 num++;
1795         }
1796         
1797         *dest = list;
1798         return True;    
1799 }
1800
1801 /**
1802  * Return true if all the elements of the list match exactly.
1803  **/
1804 BOOL str_list_compare(char **list1, char **list2)
1805 {
1806         int num;
1807         
1808         if (!list1 || !list2)
1809                 return (list1 == list2); 
1810         
1811         for (num = 0; list1[num]; num++) {
1812                 if (!list2[num])
1813                         return False;
1814                 if (!strcsequal(list1[num], list2[num]))
1815                         return False;
1816         }
1817         if (list2[num])
1818                 return False; /* if list2 has more elements than list1 fail */
1819         
1820         return True;
1821 }
1822
1823 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1824 {
1825         char **tlist;
1826         
1827         if (!list || !*list)
1828                 return;
1829         tlist = *list;
1830         for(; *tlist; tlist++) {
1831                 if (mem_ctx) {
1832                         TALLOC_FREE(*tlist);
1833                 } else {
1834                         SAFE_FREE(*tlist);
1835                 }
1836         }
1837         if (mem_ctx) {
1838                 TALLOC_FREE(*tlist);
1839         } else {
1840                 SAFE_FREE(*list);
1841         }
1842 }
1843
1844 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1845 {
1846         str_list_free_internal(mem_ctx, list);
1847 }
1848
1849 void str_list_free(char ***list)
1850 {
1851         str_list_free_internal(NULL, list);
1852 }
1853
1854 /******************************************************************************
1855  *****************************************************************************/
1856
1857 int str_list_count( const char **list )
1858 {
1859         int i = 0;
1860
1861         if ( ! list )
1862                 return 0;
1863
1864         /* count the number of list members */
1865         
1866         for ( i=0; *list; i++, list++ );
1867         
1868         return i;
1869 }
1870
1871 /******************************************************************************
1872  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1873  for the work
1874  *****************************************************************************/
1875  
1876 BOOL str_list_sub_basic( char **list, const char *smb_name )
1877 {
1878         char *s, *tmpstr;
1879         
1880         while ( *list ) {
1881                 s = *list;
1882                 tmpstr = alloc_sub_basic(smb_name, s);
1883                 if ( !tmpstr ) {
1884                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1885                         return False;
1886                 }
1887
1888                 SAFE_FREE(*list);
1889                 *list = tmpstr;
1890                         
1891                 list++;
1892         }
1893
1894         return True;
1895 }
1896
1897 /******************************************************************************
1898  substritute a specific pattern in a string list
1899  *****************************************************************************/
1900  
1901 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1902 {
1903         char *p, *s, *t;
1904         ssize_t ls, lp, li, ld, i, d;
1905
1906         if (!list)
1907                 return False;
1908         if (!pattern)
1909                 return False;
1910         if (!insert)
1911                 return False;
1912
1913         lp = (ssize_t)strlen(pattern);
1914         li = (ssize_t)strlen(insert);
1915         ld = li -lp;
1916                         
1917         while (*list) {
1918                 s = *list;
1919                 ls = (ssize_t)strlen(s);
1920
1921                 while ((p = strstr_m(s, pattern))) {
1922                         t = *list;
1923                         d = p -t;
1924                         if (ld) {
1925                                 t = (char *) SMB_MALLOC(ls +ld +1);
1926                                 if (!t) {
1927                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1928                                         return False;
1929                                 }
1930                                 memcpy(t, *list, d);
1931                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1932                                 SAFE_FREE(*list);
1933                                 *list = t;
1934                                 ls += ld;
1935                                 s = t +d +li;
1936                         }
1937                         
1938                         for (i = 0; i < li; i++) {
1939                                 switch (insert[i]) {
1940                                         case '`':
1941                                         case '"':
1942                                         case '\'':
1943                                         case ';':
1944                                         case '$':
1945                                         case '%':
1946                                         case '\r':
1947                                         case '\n':
1948                                                 t[d +i] = '_';
1949                                                 break;
1950                                         default:
1951                                                 t[d +i] = insert[i];
1952                                 }
1953                         }       
1954                 }
1955                 
1956                 
1957                 list++;
1958         }
1959         
1960         return True;
1961 }
1962
1963
1964 #define IPSTR_LIST_SEP  ","
1965 #define IPSTR_LIST_CHAR ','
1966
1967 /**
1968  * Add ip string representation to ipstr list. Used also
1969  * as part of @function ipstr_list_make
1970  *
1971  * @param ipstr_list pointer to string containing ip list;
1972  *        MUST BE already allocated and IS reallocated if necessary
1973  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1974  *        as a result of reallocation)
1975  * @param ip IP address which is to be added to list
1976  * @return pointer to string appended with new ip and possibly
1977  *         reallocated to new length
1978  **/
1979
1980 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1981 {
1982         char* new_ipstr = NULL;
1983         
1984         /* arguments checking */
1985         if (!ipstr_list || !service) return NULL;
1986
1987         /* attempt to convert ip to a string and append colon separator to it */
1988         if (*ipstr_list) {
1989                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1990                         inet_ntoa(service->ip), service->port);
1991                 SAFE_FREE(*ipstr_list);
1992         } else {
1993                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1994         }
1995         *ipstr_list = new_ipstr;
1996         return *ipstr_list;
1997 }
1998
1999
2000 /**
2001  * Allocate and initialise an ipstr list using ip adresses
2002  * passed as arguments.
2003  *
2004  * @param ipstr_list pointer to string meant to be allocated and set
2005  * @param ip_list array of ip addresses to place in the list
2006  * @param ip_count number of addresses stored in ip_list
2007  * @return pointer to allocated ip string
2008  **/
2009  
2010 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2011 {
2012         int i;
2013         
2014         /* arguments checking */
2015         if (!ip_list && !ipstr_list) return 0;
2016
2017         *ipstr_list = NULL;
2018         
2019         /* process ip addresses given as arguments */
2020         for (i = 0; i < ip_count; i++)
2021                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2022         
2023         return (*ipstr_list);
2024 }
2025
2026
2027 /**
2028  * Parse given ip string list into array of ip addresses
2029  * (as ip_service structures)  
2030  *    e.g. 192.168.1.100:389,192.168.1.78, ...
2031  *
2032  * @param ipstr ip string list to be parsed 
2033  * @param ip_list pointer to array of ip addresses which is
2034  *        allocated by this function and must be freed by caller
2035  * @return number of succesfully parsed addresses
2036  **/
2037  
2038 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2039 {
2040         fstring token_str;
2041         size_t count;
2042         int i;
2043
2044         if (!ipstr_list || !ip_list) 
2045                 return 0;
2046         
2047         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2048         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2049                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2050                 return 0;
2051         }
2052         
2053         for ( i=0; 
2054                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
2055                 i++ ) 
2056         {
2057                 struct in_addr addr;
2058                 unsigned port = 0;      
2059                 char *p = strchr(token_str, ':');
2060                 
2061                 if (p) {
2062                         *p = 0;
2063                         port = atoi(p+1);
2064                 }
2065
2066                 /* convert single token to ip address */
2067                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2068                         break;
2069                                 
2070                 (*ip_list)[i].ip = addr;
2071                 (*ip_list)[i].port = port;
2072         }
2073         
2074         return count;
2075 }
2076
2077
2078 /**
2079  * Safely free ip string list
2080  *
2081  * @param ipstr_list ip string list to be freed
2082  **/
2083
2084 void ipstr_list_free(char* ipstr_list)
2085 {
2086         SAFE_FREE(ipstr_list);
2087 }
2088
2089
2090 /**
2091  Unescape a URL encoded string, in place.
2092 **/
2093
2094 void rfc1738_unescape(char *buf)
2095 {
2096         char *p=buf;
2097
2098         while (p && *p && (p=strchr_m(p,'%'))) {
2099                 int c1 = p[1];
2100                 int c2 = p[2];
2101
2102                 if (c1 >= '0' && c1 <= '9')
2103                         c1 = c1 - '0';
2104                 else if (c1 >= 'A' && c1 <= 'F')
2105                         c1 = 10 + c1 - 'A';
2106                 else if (c1 >= 'a' && c1 <= 'f')
2107                         c1 = 10 + c1 - 'a';
2108                 else {p++; continue;}
2109
2110                 if (c2 >= '0' && c2 <= '9')
2111                         c2 = c2 - '0';
2112                 else if (c2 >= 'A' && c2 <= 'F')
2113                         c2 = 10 + c2 - 'A';
2114                 else if (c2 >= 'a' && c2 <= 'f')
2115                         c2 = 10 + c2 - 'a';
2116                 else {p++; continue;}
2117                         
2118                 *p = (c1<<4) | c2;
2119
2120                 memmove(p+1, p+3, strlen(p+3)+1);
2121                 p++;
2122         }
2123 }
2124
2125 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2126
2127 /**
2128  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2129  **/
2130 DATA_BLOB base64_decode_data_blob(const char *s)
2131 {
2132         int bit_offset, byte_offset, idx, i, n;
2133         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2134         unsigned char *d = decoded.data;
2135         char *p;
2136
2137         n=i=0;
2138
2139         while (*s && (p=strchr_m(b64,*s))) {
2140                 idx = (int)(p - b64);
2141                 byte_offset = (i*6)/8;
2142                 bit_offset = (i*6)%8;
2143                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2144                 if (bit_offset < 3) {
2145                         d[byte_offset] |= (idx << (2-bit_offset));
2146                         n = byte_offset+1;
2147                 } else {
2148                         d[byte_offset] |= (idx >> (bit_offset-2));
2149                         d[byte_offset+1] = 0;
2150                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2151                         n = byte_offset+2;
2152                 }
2153                 s++; i++;
2154         }
2155
2156         if ((n > 0) && (*s == '=')) {
2157                 n -= 1;
2158         }
2159
2160         /* fix up length */
2161         decoded.length = n;
2162         return decoded;
2163 }
2164
2165 /**
2166  * Decode a base64 string in-place - wrapper for the above
2167  **/
2168 void base64_decode_inplace(char *s)
2169 {
2170         DATA_BLOB decoded = base64_decode_data_blob(s);
2171
2172         if ( decoded.length != 0 ) {
2173                 memcpy(s, decoded.data, decoded.length);
2174
2175                 /* null terminate */
2176                 s[decoded.length] = '\0';
2177         } else {
2178                 *s = '\0';
2179         }
2180
2181         data_blob_free(&decoded);
2182 }
2183
2184 /**
2185  * Encode a base64 string into a malloc()ed string caller to free.
2186  *
2187  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2188  **/
2189 char * base64_encode_data_blob(DATA_BLOB data)
2190 {
2191         int bits = 0;
2192         int char_count = 0;
2193         size_t out_cnt, len, output_len;
2194         char *result;
2195
2196         if (!data.length || !data.data)
2197                 return NULL;
2198
2199         out_cnt = 0;
2200         len = data.length;
2201         output_len = data.length * 2;
2202         result = SMB_MALLOC(output_len); /* get us plenty of space */
2203
2204         while (len-- && out_cnt < (data.length * 2) - 5) {
2205                 int c = (unsigned char) *(data.data++);
2206                 bits += c;
2207                 char_count++;
2208                 if (char_count == 3) {
2209                         result[out_cnt++] = b64[bits >> 18];
2210                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2211                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2212             result[out_cnt++] = b64[bits & 0x3f];
2213             bits = 0;
2214             char_count = 0;
2215         } else {
2216             bits <<= 8;
2217         }
2218     }
2219     if (char_count != 0) {
2220         bits <<= 16 - (8 * char_count);
2221         result[out_cnt++] = b64[bits >> 18];
2222         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2223         if (char_count == 1) {
2224             result[out_cnt++] = '=';
2225             result[out_cnt++] = '=';
2226         } else {
2227             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2228             result[out_cnt++] = '=';
2229         }
2230     }
2231     result[out_cnt] = '\0';     /* terminate */
2232     return result;
2233 }
2234
2235 /* read a SMB_BIG_UINT from a string */
2236 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2237 {
2238
2239         SMB_BIG_UINT val = -1;
2240         const char *p = nptr;
2241         
2242         while (p && *p && isspace(*p))
2243                 p++;
2244 #ifdef LARGE_SMB_OFF_T
2245         sscanf(p,"%llu",&val);  
2246 #else /* LARGE_SMB_OFF_T */
2247         sscanf(p,"%lu",&val);
2248 #endif /* LARGE_SMB_OFF_T */
2249         if (entptr) {
2250                 while (p && *p && isdigit(*p))
2251                         p++;
2252                 *entptr = p;
2253         }
2254
2255         return val;
2256 }
2257
2258 void string_append(char **left, const char *right)
2259 {
2260         int new_len = strlen(right) + 1;
2261
2262         if (*left == NULL) {
2263                 *left = SMB_MALLOC(new_len);
2264                 *left[0] = '\0';
2265         } else {
2266                 new_len += strlen(*left);
2267                 *left = SMB_REALLOC(*left, new_len);
2268         }
2269
2270         if (*left == NULL) {
2271                 return;
2272         }
2273
2274         safe_strcat(*left, right, new_len-1);
2275 }
2276
2277 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2278                          const char *str, const char ***strings,
2279                          int *num)
2280 {
2281         char *dup_str = talloc_strdup(mem_ctx, str);
2282
2283         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2284
2285         if ((*strings == NULL) || (dup_str == NULL))
2286                 return False;
2287
2288         (*strings)[*num] = dup_str;
2289         *num += 1;
2290         return True;
2291 }
2292
2293 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2294  * error checking in between. The indiation that something weird happened is
2295  * string==NULL */
2296
2297 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2298                     size_t *bufsize, const char *fmt, ...)
2299 {
2300         va_list ap;
2301         char *newstr;
2302         int ret;
2303         BOOL increased;
2304
2305         /* len<0 is an internal marker that something failed */
2306         if (*len < 0)
2307                 goto error;
2308
2309         if (*string == NULL) {
2310                 if (*bufsize == 0)
2311                         *bufsize = 128;
2312
2313                 if (mem_ctx != NULL)
2314                         *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2315                 else
2316                         *string = SMB_MALLOC_ARRAY(char, *bufsize);
2317
2318                 if (*string == NULL)
2319                         goto error;
2320         }
2321
2322         va_start(ap, fmt);
2323         ret = vasprintf(&newstr, fmt, ap);
2324         va_end(ap);
2325
2326         if (ret < 0)
2327                 goto error;
2328
2329         increased = False;
2330
2331         while ((*len)+ret >= *bufsize) {
2332                 increased = True;
2333                 *bufsize *= 2;
2334                 if (*bufsize >= (1024*1024*256))
2335                         goto error;
2336         }
2337
2338         if (increased) {
2339                 if (mem_ctx != NULL) {
2340                         *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2341                                                        *bufsize);
2342                 } else {
2343                         *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2344                 }
2345
2346                 if (*string == NULL) {
2347                         goto error;
2348                 }
2349         }
2350
2351         StrnCpy((*string)+(*len), newstr, ret);
2352         (*len) += ret;
2353         free(newstr);
2354         return;
2355
2356  error:
2357         *len = -1;
2358         *string = NULL;
2359 }
2360
2361 /*
2362    Returns the substring from src between the first occurrence of
2363    the char "front" and the first occurence of the char "back".
2364    Mallocs the return string which must be freed.  Not for use
2365    with wide character strings.
2366 */
2367 char *sstring_sub(const char *src, char front, char back)
2368 {
2369         char *temp1, *temp2, *temp3;
2370         ptrdiff_t len;
2371
2372         temp1 = strchr(src, front);
2373         if (temp1 == NULL) return NULL;
2374         temp2 = strchr(src, back);
2375         if (temp2 == NULL) return NULL;
2376         len = temp2 - temp1;
2377         if (len <= 0) return NULL;
2378         temp3 = (char*)SMB_MALLOC(len);
2379         if (temp3 == NULL) {
2380                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2381                 return NULL;
2382         }
2383         memcpy(temp3, temp1+1, len-1);
2384         temp3[len-1] = '\0';
2385         return temp3;
2386 }
2387
2388 /********************************************************************
2389  Check a string for any occurrences of a specified list of invalid
2390  characters.
2391 ********************************************************************/
2392
2393 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2394 {
2395         int i;
2396
2397         for ( i=0; i<max_len && name[i]; i++ ) {
2398                 /* fail if strchr_m() finds one of the invalid characters */
2399                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2400                         return False;
2401                 }
2402         }
2403
2404         return True;
2405 }
2406