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