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