Added Andrew Bartlett's patch to use an allocated buffer for count_chars.
[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 == '\"' || *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;
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         return(count);
571 }
572
573 /**
574  Safe string copy into a known length string. maxlength does not
575  include the terminating zero.
576 **/
577
578 char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
579 {
580         size_t len;
581
582         if (!dest) {
583                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
584                 return NULL;
585         }
586
587 #ifdef DEVELOPER
588         clobber_region(fn,line,dest, maxlength+1);
589 #endif
590
591         if (!src) {
592                 *dest = 0;
593                 return dest;
594         }  
595
596         len = strnlen(src, maxlength+1);
597
598         if (len > maxlength) {
599                 DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
600                          (unsigned long)(len-maxlength), (unsigned long)len, 
601                          (unsigned long)maxlength, src));
602                 len = maxlength;
603         }
604       
605         memmove(dest, src, len);
606         dest[len] = 0;
607         return dest;
608 }  
609
610 /**
611  Safe string cat into a string. maxlength does not
612  include the terminating zero.
613 **/
614 char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
615 {
616         size_t src_len, dest_len;
617
618         if (!dest) {
619                 DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
620                 return NULL;
621         }
622
623         if (!src)
624                 return dest;
625         
626         src_len = strnlen(src, maxlength + 1);
627         dest_len = strnlen(dest, maxlength + 1);
628
629 #ifdef DEVELOPER
630         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
631 #endif
632
633         if (src_len + dest_len > maxlength) {
634                 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
635                          (int)(src_len + dest_len - maxlength), src));
636                 if (maxlength > dest_len) {
637                         memcpy(&dest[dest_len], src, maxlength - dest_len);
638                 }
639                 dest[maxlength] = 0;
640                 return NULL;
641         }
642
643         memcpy(&dest[dest_len], src, src_len);
644         dest[dest_len + src_len] = 0;
645         return dest;
646 }
647
648 /**
649  Paranoid strcpy into a buffer of given length (includes terminating
650  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
651  and replaces with '_'. Deliberately does *NOT* check for multibyte
652  characters. Don't change it !
653 **/
654 char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
655 {
656         size_t len, i;
657
658 #ifdef DEVELOPER
659         clobber_region(fn, line, dest, maxlength);
660 #endif
661
662         if (!dest) {
663                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
664                 return NULL;
665         }
666
667         if (!src) {
668                 *dest = 0;
669                 return dest;
670         }  
671
672         len = strlen(src);
673         if (len >= maxlength)
674                 len = maxlength - 1;
675
676         if (!other_safe_chars)
677                 other_safe_chars = "";
678
679         for(i = 0; i < len; i++) {
680                 int val = (src[i] & 0xff);
681                 if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
682                         dest[i] = src[i];
683                 else
684                         dest[i] = '_';
685         }
686
687         dest[i] = '\0';
688
689         return dest;
690 }
691
692 /**
693  Like strncpy but always null terminates. Make sure there is room!
694  The variable n should always be one less than the available size.
695 **/
696 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
697 {
698         char *d = dest;
699
700 #ifdef DEVELOPER
701         clobber_region(fn, line, dest, n+1);
702 #endif
703
704         if (!dest) {
705                 DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
706                 return(NULL);
707         }
708
709         if (!src) {
710                 *dest = 0;
711                 return(dest);
712         }
713         
714         while (n-- && (*d = *src)) {
715                 d++;
716                 src++;
717         }
718
719         *d = 0;
720         return(dest);
721 }
722
723 #if 0
724 /**
725  Like strncpy but copies up to the character marker.  always null terminates.
726  returns a pointer to the character marker in the source string (src).
727 **/
728
729 static char *strncpyn(char *dest, const char *src, size_t n, char c)
730 {
731         char *p;
732         size_t str_len;
733
734 #ifdef DEVELOPER
735         clobber_region(dest, n+1);
736 #endif
737         p = strchr_m(src, c);
738         if (p == NULL) {
739                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
740                 return NULL;
741         }
742
743         str_len = PTR_DIFF(p, src);
744         strncpy(dest, src, MIN(n, str_len));
745         dest[str_len] = '\0';
746
747         return p;
748 }
749 #endif
750
751 /**
752  Routine to get hex characters and turn them into a 16 byte array.
753  the array can be variable length, and any non-hex-numeric
754  characters are skipped.  "0xnn" or "0Xnn" is specially catered
755  for.
756
757  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
758
759 **/
760
761 size_t strhex_to_str(char *p, size_t len, const char *strhex)
762 {
763         size_t i;
764         size_t num_chars = 0;
765         unsigned char   lonybble, hinybble;
766         const char     *hexchars = "0123456789ABCDEF";
767         char           *p1 = NULL, *p2 = NULL;
768
769         for (i = 0; i < len && strhex[i] != 0; i++) {
770                 if (strnequal(hexchars, "0x", 2)) {
771                         i++; /* skip two chars */
772                         continue;
773                 }
774
775                 if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
776                         break;
777
778                 i++; /* next hex digit */
779
780                 if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
781                         break;
782
783                 /* get the two nybbles */
784                 hinybble = PTR_DIFF(p1, hexchars);
785                 lonybble = PTR_DIFF(p2, hexchars);
786
787                 p[num_chars] = (hinybble << 4) | lonybble;
788                 num_chars++;
789
790                 p1 = NULL;
791                 p2 = NULL;
792         }
793         return num_chars;
794 }
795
796 /**
797  * Routine to print a buffer as HEX digits, into an allocated string.
798  */
799
800 void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
801 {
802         int i;
803         char *hex_buffer;
804
805         *out_hex_buffer = smb_xmalloc((len*2)+1);
806         hex_buffer = *out_hex_buffer;
807
808         for (i = 0; i < len; i++)
809                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
810 }
811
812 /**
813  Check if a string is part of a list.
814 **/
815
816 BOOL in_list(char *s,char *list,BOOL casesensitive)
817 {
818         pstring tok;
819         const char *p=list;
820
821         if (!list)
822                 return(False);
823
824         while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
825                 if (casesensitive) {
826                         if (strcmp(tok,s) == 0)
827                                 return(True);
828                 } else {
829                         if (StrCaseCmp(tok,s) == 0)
830                                 return(True);
831                 }
832         }
833         return(False);
834 }
835
836 /* this is used to prevent lots of mallocs of size 1 */
837 static char *null_string = NULL;
838
839 /**
840  Set a string value, allocing the space for the string
841 **/
842
843 static BOOL string_init(char **dest,const char *src)
844 {
845         size_t l;
846         if (!src)     
847                 src = "";
848
849         l = strlen(src);
850
851         if (l == 0) {
852                 if (!null_string) {
853                         if((null_string = (char *)malloc(1)) == NULL) {
854                                 DEBUG(0,("string_init: malloc fail for null_string.\n"));
855                                 return False;
856                         }
857                         *null_string = 0;
858                 }
859                 *dest = null_string;
860         } else {
861                 (*dest) = strdup(src);
862                 if ((*dest) == NULL) {
863                         DEBUG(0,("Out of memory in string_init\n"));
864                         return False;
865                 }
866         }
867         return(True);
868 }
869
870 /**
871  Free a string value.
872 **/
873
874 void string_free(char **s)
875 {
876         if (!s || !(*s))
877                 return;
878         if (*s == null_string)
879                 *s = NULL;
880         SAFE_FREE(*s);
881 }
882
883 /**
884  Set a string value, deallocating any existing space, and allocing the space
885  for the string
886 **/
887
888 BOOL string_set(char **dest,const char *src)
889 {
890         string_free(dest);
891         return(string_init(dest,src));
892 }
893
894 /**
895  Substitute a string for a pattern in another string. Make sure there is 
896  enough room!
897
898  This routine looks for pattern in s and replaces it with 
899  insert. It may do multiple replacements.
900
901  Any of " ; ' $ or ` in the insert string are replaced with _
902  if len==0 then the string cannot be extended. This is different from the old
903  use of len==0 which was for no length checks to be done.
904 **/
905
906 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
907 {
908         char *p;
909         ssize_t ls,lp,li, i;
910
911         if (!insert || !pattern || !*pattern || !s)
912                 return;
913
914         ls = (ssize_t)strlen(s);
915         lp = (ssize_t)strlen(pattern);
916         li = (ssize_t)strlen(insert);
917
918         if (len == 0)
919                 len = ls + 1; /* len is number of *bytes* */
920
921         while (lp <= ls && (p = strstr(s,pattern))) {
922                 if (ls + (li-lp) >= len) {
923                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
924                                  (int)(ls + (li-lp) - len),
925                                  pattern, (int)len));
926                         break;
927                 }
928                 if (li != lp) {
929                         memmove(p+li,p+lp,strlen(p+lp)+1);
930                 }
931                 for (i=0;i<li;i++) {
932                         switch (insert[i]) {
933                         case '`':
934                         case '"':
935                         case '\'':
936                         case ';':
937                         case '$':
938                         case '%':
939                         case '\r':
940                         case '\n':
941                                 p[i] = '_';
942                                 break;
943                         default:
944                                 p[i] = insert[i];
945                         }
946                 }
947                 s = p + li;
948                 ls += (li-lp);
949         }
950 }
951
952 void fstring_sub(char *s,const char *pattern,const char *insert)
953 {
954         string_sub(s, pattern, insert, sizeof(fstring));
955 }
956
957 void pstring_sub(char *s,const char *pattern,const char *insert)
958 {
959         string_sub(s, pattern, insert, sizeof(pstring));
960 }
961
962 /**
963  Similar to string_sub, but it will accept only allocated strings
964  and may realloc them so pay attention at what you pass on no
965  pointers inside strings, no pstrings or const may be passed
966  as string.
967 **/
968
969 char *realloc_string_sub(char *string, const char *pattern, const char *insert)
970 {
971         char *p, *in;
972         char *s;
973         ssize_t ls,lp,li,ld, i;
974
975         if (!insert || !pattern || !*pattern || !string || !*string)
976                 return NULL;
977
978         s = string;
979
980         in = strdup(insert);
981         if (!in) {
982                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
983                 return NULL;
984         }
985         ls = (ssize_t)strlen(s);
986         lp = (ssize_t)strlen(pattern);
987         li = (ssize_t)strlen(insert);
988         ld = li - lp;
989         for (i=0;i<li;i++) {
990                 switch (in[i]) {
991                         case '`':
992                         case '"':
993                         case '\'':
994                         case ';':
995                         case '$':
996                         case '%':
997                         case '\r':
998                         case '\n':
999                                 in[i] = '_';
1000                         default:
1001                                 /* ok */
1002                                 break;
1003                 }
1004         }
1005         
1006         while ((p = strstr(s,pattern))) {
1007                 if (ld > 0) {
1008                         int offset = PTR_DIFF(s,string);
1009                         char *t = Realloc(string, ls + ld + 1);
1010                         if (!t) {
1011                                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
1012                                 SAFE_FREE(in);
1013                                 return NULL;
1014                         }
1015                         string = t;
1016                         p = t + offset + (p - s);
1017                 }
1018                 if (li != lp) {
1019                         memmove(p+li,p+lp,strlen(p+lp)+1);
1020                 }
1021                 memcpy(p, in, li);
1022                 s = p + li;
1023                 ls += ld;
1024         }
1025         SAFE_FREE(in);
1026         return string;
1027 }
1028
1029 /**
1030  Similar to string_sub() but allows for any character to be substituted. 
1031  Use with caution!
1032  if len==0 then the string cannot be extended. This is different from the old
1033  use of len==0 which was for no length checks to be done.
1034 **/
1035
1036 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1037 {
1038         char *p;
1039         ssize_t ls,lp,li;
1040
1041         if (!insert || !pattern || !s)
1042                 return;
1043
1044         ls = (ssize_t)strlen(s);
1045         lp = (ssize_t)strlen(pattern);
1046         li = (ssize_t)strlen(insert);
1047
1048         if (!*pattern)
1049                 return;
1050         
1051         if (len == 0)
1052                 len = ls + 1; /* len is number of *bytes* */
1053         
1054         while (lp <= ls && (p = strstr(s,pattern))) {
1055                 if (ls + (li-lp) >= len) {
1056                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1057                                  (int)(ls + (li-lp) - len),
1058                                  pattern, (int)len));
1059                         break;
1060                 }
1061                 if (li != lp) {
1062                         memmove(p+li,p+lp,strlen(p+lp)+1);
1063                 }
1064                 memcpy(p, insert, li);
1065                 s = p + li;
1066                 ls += (li-lp);
1067         }
1068 }
1069
1070 /**
1071  Similar to all_string_sub but for unicode strings.
1072  Return a new allocated unicode string.
1073  similar to string_sub() but allows for any character to be substituted.
1074  Use with caution!
1075 **/
1076
1077 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1078                                 const smb_ucs2_t *insert)
1079 {
1080         smb_ucs2_t *r, *rp;
1081         const smb_ucs2_t *sp;
1082         size_t  lr, lp, li, lt;
1083
1084         if (!insert || !pattern || !*pattern || !s)
1085                 return NULL;
1086
1087         lt = (size_t)strlen_w(s);
1088         lp = (size_t)strlen_w(pattern);
1089         li = (size_t)strlen_w(insert);
1090
1091         if (li > lp) {
1092                 const smb_ucs2_t *st = s;
1093                 int ld = li - lp;
1094                 while ((sp = strstr_w(st, pattern))) {
1095                         st = sp + lp;
1096                         lt += ld;
1097                 }
1098         }
1099
1100         r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t)));
1101         if (!r) {
1102                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1103                 return NULL;
1104         }
1105
1106         while ((sp = strstr_w(s, pattern))) {
1107                 memcpy(rp, s, (sp - s));
1108                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1109                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1110                 s = sp + lp;
1111                 rp += li;
1112         }
1113         lr = ((rp - r) / sizeof(smb_ucs2_t));
1114         if (lr < lt) {
1115                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1116                 rp += (lt - lr);
1117         }
1118         *rp = 0;
1119
1120         return r;
1121 }
1122
1123 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1124                                              const char *insert)
1125 {
1126         wpstring p, i;
1127
1128         if (!insert || !pattern || !s)
1129                 return NULL;
1130         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1131         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1132         return all_string_sub_w(s, p, i);
1133 }
1134
1135 #if 0
1136 /**
1137  Splits out the front and back at a separator.
1138 **/
1139
1140 static void split_at_last_component(char *path, char *front, char sep, char *back)
1141 {
1142         char *p = strrchr_m(path, sep);
1143
1144         if (p != NULL)
1145                 *p = 0;
1146
1147         if (front != NULL)
1148                 pstrcpy(front, path);
1149
1150         if (p != NULL) {
1151                 if (back != NULL)
1152                         pstrcpy(back, p+1);
1153                 *p = '\\';
1154         } else {
1155                 if (back != NULL)
1156                         back[0] = 0;
1157         }
1158 }
1159 #endif
1160
1161 /**
1162  Write an octal as a string.
1163 **/
1164
1165 const char *octal_string(int i)
1166 {
1167         static char ret[64];
1168         if (i == -1)
1169                 return "-1";
1170         slprintf(ret, sizeof(ret)-1, "0%o", i);
1171         return ret;
1172 }
1173
1174
1175 /**
1176  Truncate a string at a specified length.
1177 **/
1178
1179 char *string_truncate(char *s, unsigned int length)
1180 {
1181         if (s && strlen(s) > length)
1182                 s[length] = 0;
1183         return s;
1184 }
1185
1186 /**
1187  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1188  We convert via ucs2 for now.
1189 **/
1190
1191 char *strchr_m(const char *src, char c)
1192 {
1193         wpstring ws;
1194         pstring s2;
1195         smb_ucs2_t *p;
1196         const char *s;
1197
1198         /* this is quite a common operation, so we want it to be
1199            fast. We optimise for the ascii case, knowing that all our
1200            supported multi-byte character sets are ascii-compatible
1201            (ie. they match for the first 128 chars) */
1202
1203         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1204                 if (*s == c)
1205                         return (char *)s;
1206         }
1207
1208         if (!*s)
1209                 return NULL;
1210
1211 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1212         /* With compose characters we must restart from the beginning. JRA. */
1213         s = src;
1214 #endif
1215
1216         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1217         p = strchr_w(ws, UCS2_CHAR(c));
1218         if (!p)
1219                 return NULL;
1220         *p = 0;
1221         pull_ucs2_pstring(s2, ws);
1222         return (char *)(s+strlen(s2));
1223 }
1224
1225 char *strrchr_m(const char *s, char c)
1226 {
1227         /* this is quite a common operation, so we want it to be
1228            fast. We optimise for the ascii case, knowing that all our
1229            supported multi-byte character sets are ascii-compatible
1230            (ie. they match for the first 128 chars). Also, in Samba
1231            we only search for ascii characters in 'c' and that
1232            in all mb character sets with a compound character
1233            containing c, if 'c' is not a match at position
1234            p, then p[-1] > 0x7f. JRA. */
1235
1236         {
1237                 size_t len = strlen(s);
1238                 const char *cp = s;
1239                 BOOL got_mb = False;
1240
1241                 if (len == 0)
1242                         return NULL;
1243                 cp += (len - 1);
1244                 do {
1245                         if (c == *cp) {
1246                                 /* Could be a match. Part of a multibyte ? */
1247                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1248                                         /* Yep - go slow :-( */
1249                                         got_mb = True;
1250                                         break;
1251                                 }
1252                                 /* No - we have a match ! */
1253                                 return (char *)cp;
1254                         }
1255                 } while (cp-- != s);
1256                 if (!got_mb)
1257                         return NULL;
1258         }
1259
1260         /* String contained a non-ascii char. Slow path. */
1261         {
1262                 wpstring ws;
1263                 pstring s2;
1264                 smb_ucs2_t *p;
1265
1266                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1267                 p = strrchr_w(ws, UCS2_CHAR(c));
1268                 if (!p)
1269                         return NULL;
1270                 *p = 0;
1271                 pull_ucs2_pstring(s2, ws);
1272                 return (char *)(s+strlen(s2));
1273         }
1274 }
1275
1276 /***********************************************************************
1277  Return the equivalent of doing strrchr 'n' times - always going
1278  backwards.
1279 ***********************************************************************/
1280
1281 char *strnrchr_m(const char *s, char c, unsigned int n)
1282 {
1283         wpstring ws;
1284         pstring s2;
1285         smb_ucs2_t *p;
1286
1287         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1288         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1289         if (!p)
1290                 return NULL;
1291         *p = 0;
1292         pull_ucs2_pstring(s2, ws);
1293         return (char *)(s+strlen(s2));
1294 }
1295
1296 /**
1297  Convert a string to lower case.
1298 **/
1299
1300 void strlower_m(char *s)
1301 {
1302         size_t len;
1303
1304         /* this is quite a common operation, so we want it to be
1305            fast. We optimise for the ascii case, knowing that all our
1306            supported multi-byte character sets are ascii-compatible
1307            (ie. they match for the first 128 chars) */
1308
1309         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1310                 *s = tolower((unsigned char)*s);
1311                 s++;
1312         }
1313
1314         if (!*s)
1315                 return;
1316
1317         /* I assume that lowercased string takes the same number of bytes
1318          * as source string even in UTF-8 encoding. (VIV) */
1319         len = strlen(s) + 1;
1320         errno = 0;
1321         unix_strlower(s,len,s,len);     
1322         /* Catch mb conversion errors that may not terminate. */
1323         if (errno)
1324                 s[len-1] = '\0';
1325 }
1326
1327 /**
1328  Convert a string to upper case.
1329 **/
1330
1331 void strupper_m(char *s)
1332 {
1333         size_t len;
1334
1335         /* this is quite a common operation, so we want it to be
1336            fast. We optimise for the ascii case, knowing that all our
1337            supported multi-byte character sets are ascii-compatible
1338            (ie. they match for the first 128 chars) */
1339
1340         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1341                 *s = toupper((unsigned char)*s);
1342                 s++;
1343         }
1344
1345         if (!*s)
1346                 return;
1347
1348         /* I assume that lowercased string takes the same number of bytes
1349          * as source string even in multibyte encoding. (VIV) */
1350         len = strlen(s) + 1;
1351         errno = 0;
1352         unix_strupper(s,len,s,len);     
1353         /* Catch mb conversion errors that may not terminate. */
1354         if (errno)
1355                 s[len-1] = '\0';
1356 }
1357
1358 /**
1359  Return a RFC2254 binary string representation of a buffer.
1360  Used in LDAP filters.
1361  Caller must free.
1362 **/
1363
1364 char *binary_string(char *buf, int len)
1365 {
1366         char *s;
1367         int i, j;
1368         const char *hex = "0123456789ABCDEF";
1369         s = malloc(len * 3 + 1);
1370         if (!s)
1371                 return NULL;
1372         for (j=i=0;i<len;i++) {
1373                 s[j] = '\\';
1374                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1375                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1376                 j += 3;
1377         }
1378         s[j] = 0;
1379         return s;
1380 }
1381
1382 /**
1383  Just a typesafety wrapper for snprintf into a pstring.
1384 **/
1385
1386  int pstr_sprintf(pstring s, const char *fmt, ...)
1387 {
1388         va_list ap;
1389         int ret;
1390
1391         va_start(ap, fmt);
1392         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1393         va_end(ap);
1394         return ret;
1395 }
1396
1397
1398 /**
1399  Just a typesafety wrapper for snprintf into a fstring.
1400 **/
1401
1402 int fstr_sprintf(fstring s, const char *fmt, ...)
1403 {
1404         va_list ap;
1405         int ret;
1406
1407         va_start(ap, fmt);
1408         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1409         va_end(ap);
1410         return ret;
1411 }
1412
1413
1414 #ifndef HAVE_STRNDUP
1415 /**
1416  Some platforms don't have strndup.
1417 **/
1418
1419  char *strndup(const char *s, size_t n)
1420 {
1421         char *ret;
1422         
1423         n = strnlen(s, n);
1424         ret = malloc(n+1);
1425         if (!ret)
1426                 return NULL;
1427         memcpy(ret, s, n);
1428         ret[n] = 0;
1429
1430         return ret;
1431 }
1432 #endif
1433
1434 #ifndef HAVE_STRNLEN
1435 /**
1436  Some platforms don't have strnlen
1437 **/
1438
1439  size_t strnlen(const char *s, size_t n)
1440 {
1441         int i;
1442         for (i=0; s[i] && i<n; i++)
1443                 /* noop */ ;
1444         return i;
1445 }
1446 #endif
1447
1448 /**
1449  List of Strings manipulation functions
1450 **/
1451
1452 #define S_LIST_ABS 16 /* List Allocation Block Size */
1453
1454 char **str_list_make(const char *string, const char *sep)
1455 {
1456         char **list, **rlist;
1457         const char *str;
1458         char *s;
1459         int num, lsize;
1460         pstring tok;
1461         
1462         if (!string || !*string)
1463                 return NULL;
1464         s = strdup(string);
1465         if (!s) {
1466                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1467                 return NULL;
1468         }
1469         if (!sep) sep = LIST_SEP;
1470         
1471         num = lsize = 0;
1472         list = NULL;
1473         
1474         str = s;
1475         while (next_token(&str, tok, sep, sizeof(tok))) {               
1476                 if (num == lsize) {
1477                         lsize += S_LIST_ABS;
1478                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1479                         if (!rlist) {
1480                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1481                                 str_list_free(&list);
1482                                 SAFE_FREE(s);
1483                                 return NULL;
1484                         } else
1485                                 list = rlist;
1486                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1487                 }
1488                 
1489                 list[num] = strdup(tok);
1490                 if (!list[num]) {
1491                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1492                         str_list_free(&list);
1493                         SAFE_FREE(s);
1494                         return NULL;
1495                 }
1496         
1497                 num++;  
1498         }
1499         
1500         SAFE_FREE(s);
1501         return list;
1502 }
1503
1504 BOOL str_list_copy(char ***dest, const char **src)
1505 {
1506         char **list, **rlist;
1507         int num, lsize;
1508         
1509         *dest = NULL;
1510         if (!src)
1511                 return False;
1512         
1513         num = lsize = 0;
1514         list = NULL;
1515                 
1516         while (src[num]) {
1517                 if (num == lsize) {
1518                         lsize += S_LIST_ABS;
1519                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1520                         if (!rlist) {
1521                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1522                                 str_list_free(&list);
1523                                 return False;
1524                         } else
1525                                 list = rlist;
1526                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1527                 }
1528                 
1529                 list[num] = strdup(src[num]);
1530                 if (!list[num]) {
1531                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1532                         str_list_free(&list);
1533                         return False;
1534                 }
1535
1536                 num++;
1537         }
1538         
1539         *dest = list;
1540         return True;    
1541 }
1542
1543 /**
1544  * Return true if all the elements of the list match exactly.
1545  **/
1546 BOOL str_list_compare(char **list1, char **list2)
1547 {
1548         int num;
1549         
1550         if (!list1 || !list2)
1551                 return (list1 == list2); 
1552         
1553         for (num = 0; list1[num]; num++) {
1554                 if (!list2[num])
1555                         return False;
1556                 if (!strcsequal(list1[num], list2[num]))
1557                         return False;
1558         }
1559         if (list2[num])
1560                 return False; /* if list2 has more elements than list1 fail */
1561         
1562         return True;
1563 }
1564
1565 void str_list_free(char ***list)
1566 {
1567         char **tlist;
1568         
1569         if (!list || !*list)
1570                 return;
1571         tlist = *list;
1572         for(; *tlist; tlist++)
1573                 SAFE_FREE(*tlist);
1574         SAFE_FREE(*list);
1575 }
1576
1577 /******************************************************************************
1578  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1579  for the work
1580  *****************************************************************************/
1581  
1582 BOOL str_list_sub_basic( char **list, const char *smb_name )
1583 {
1584         char *s, *tmpstr;
1585         
1586         while ( *list ) {
1587                 s = *list;
1588                 tmpstr = alloc_sub_basic(smb_name, s);
1589                 if ( !tmpstr ) {
1590                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1591                         return False;
1592                 }
1593
1594                 *list = tmpstr;
1595                         
1596                 list++;
1597         }
1598
1599         return True;
1600 }
1601
1602 /******************************************************************************
1603  substritute a specific pattern in a string list
1604  *****************************************************************************/
1605  
1606 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1607 {
1608         char *p, *s, *t;
1609         ssize_t ls, lp, li, ld, i, d;
1610
1611         if (!list)
1612                 return False;
1613         if (!pattern)
1614                 return False;
1615         if (!insert)
1616                 return False;
1617
1618         lp = (ssize_t)strlen(pattern);
1619         li = (ssize_t)strlen(insert);
1620         ld = li -lp;
1621                         
1622         while (*list) {
1623                 s = *list;
1624                 ls = (ssize_t)strlen(s);
1625
1626                 while ((p = strstr(s, pattern))) {
1627                         t = *list;
1628                         d = p -t;
1629                         if (ld) {
1630                                 t = (char *) malloc(ls +ld +1);
1631                                 if (!t) {
1632                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1633                                         return False;
1634                                 }
1635                                 memcpy(t, *list, d);
1636                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1637                                 SAFE_FREE(*list);
1638                                 *list = t;
1639                                 ls += ld;
1640                                 s = t +d +li;
1641                         }
1642                         
1643                         for (i = 0; i < li; i++) {
1644                                 switch (insert[i]) {
1645                                         case '`':
1646                                         case '"':
1647                                         case '\'':
1648                                         case ';':
1649                                         case '$':
1650                                         case '%':
1651                                         case '\r':
1652                                         case '\n':
1653                                                 t[d +i] = '_';
1654                                                 break;
1655                                         default:
1656                                                 t[d +i] = insert[i];
1657                                 }
1658                         }       
1659                 }
1660                 
1661                 
1662                 list++;
1663         }
1664         
1665         return True;
1666 }
1667
1668
1669 #define IPSTR_LIST_SEP  ","
1670 #define IPSTR_LIST_CHAR ','
1671
1672 /**
1673  * Add ip string representation to ipstr list. Used also
1674  * as part of @function ipstr_list_make
1675  *
1676  * @param ipstr_list pointer to string containing ip list;
1677  *        MUST BE already allocated and IS reallocated if necessary
1678  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1679  *        as a result of reallocation)
1680  * @param ip IP address which is to be added to list
1681  * @return pointer to string appended with new ip and possibly
1682  *         reallocated to new length
1683  **/
1684
1685 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1686 {
1687         char* new_ipstr = NULL;
1688         
1689         /* arguments checking */
1690         if (!ipstr_list || !service) return NULL;
1691
1692         /* attempt to convert ip to a string and append colon separator to it */
1693         if (*ipstr_list) {
1694                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1695                         inet_ntoa(service->ip), service->port);
1696                 SAFE_FREE(*ipstr_list);
1697         } else {
1698                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1699         }
1700         *ipstr_list = new_ipstr;
1701         return *ipstr_list;
1702 }
1703
1704
1705 /**
1706  * Allocate and initialise an ipstr list using ip adresses
1707  * passed as arguments.
1708  *
1709  * @param ipstr_list pointer to string meant to be allocated and set
1710  * @param ip_list array of ip addresses to place in the list
1711  * @param ip_count number of addresses stored in ip_list
1712  * @return pointer to allocated ip string
1713  **/
1714  
1715 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1716 {
1717         int i;
1718         
1719         /* arguments checking */
1720         if (!ip_list && !ipstr_list) return 0;
1721
1722         *ipstr_list = NULL;
1723         
1724         /* process ip addresses given as arguments */
1725         for (i = 0; i < ip_count; i++)
1726                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1727         
1728         return (*ipstr_list);
1729 }
1730
1731
1732 /**
1733  * Parse given ip string list into array of ip addresses
1734  * (as ip_service structures)  
1735  *    e.g. 192.168.1.100:389,192.168.1.78, ...
1736  *
1737  * @param ipstr ip string list to be parsed 
1738  * @param ip_list pointer to array of ip addresses which is
1739  *        allocated by this function and must be freed by caller
1740  * @return number of succesfully parsed addresses
1741  **/
1742  
1743 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1744 {
1745         fstring token_str;
1746         size_t count;
1747         int i;
1748
1749         if (!ipstr_list || !ip_list) 
1750                 return 0;
1751         
1752         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1753         if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1754                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1755                 return 0;
1756         }
1757         
1758         for ( i=0; 
1759                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
1760                 i++ ) 
1761         {
1762                 struct in_addr addr;
1763                 unsigned port = 0;      
1764                 char *p = strchr(token_str, ':');
1765                 
1766                 if (p) {
1767                         *p = 0;
1768                         port = atoi(p+1);
1769                 }
1770
1771                 /* convert single token to ip address */
1772                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1773                         break;
1774                                 
1775                 (*ip_list)[i].ip = addr;
1776                 (*ip_list)[i].port = port;
1777         }
1778         
1779         return count;
1780 }
1781
1782
1783 /**
1784  * Safely free ip string list
1785  *
1786  * @param ipstr_list ip string list to be freed
1787  **/
1788
1789 void ipstr_list_free(char* ipstr_list)
1790 {
1791         SAFE_FREE(ipstr_list);
1792 }
1793
1794
1795 /**
1796  Unescape a URL encoded string, in place.
1797 **/
1798
1799 void rfc1738_unescape(char *buf)
1800 {
1801         char *p=buf;
1802
1803         while (p && *p && (p=strchr_m(p,'%'))) {
1804                 int c1 = p[1];
1805                 int c2 = p[2];
1806
1807                 if (c1 >= '0' && c1 <= '9')
1808                         c1 = c1 - '0';
1809                 else if (c1 >= 'A' && c1 <= 'F')
1810                         c1 = 10 + c1 - 'A';
1811                 else if (c1 >= 'a' && c1 <= 'f')
1812                         c1 = 10 + c1 - 'a';
1813                 else {p++; continue;}
1814
1815                 if (c2 >= '0' && c2 <= '9')
1816                         c2 = c2 - '0';
1817                 else if (c2 >= 'A' && c2 <= 'F')
1818                         c2 = 10 + c2 - 'A';
1819                 else if (c2 >= 'a' && c2 <= 'f')
1820                         c2 = 10 + c2 - 'a';
1821                 else {p++; continue;}
1822                         
1823                 *p = (c1<<4) | c2;
1824
1825                 memmove(p+1, p+3, strlen(p+3)+1);
1826                 p++;
1827         }
1828 }
1829
1830 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1831
1832 /**
1833  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1834  **/
1835 DATA_BLOB base64_decode_data_blob(const char *s)
1836 {
1837         int bit_offset, byte_offset, idx, i, n;
1838         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1839         unsigned char *d = decoded.data;
1840         char *p;
1841
1842         n=i=0;
1843
1844         while (*s && (p=strchr_m(b64,*s))) {
1845                 idx = (int)(p - b64);
1846                 byte_offset = (i*6)/8;
1847                 bit_offset = (i*6)%8;
1848                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1849                 if (bit_offset < 3) {
1850                         d[byte_offset] |= (idx << (2-bit_offset));
1851                         n = byte_offset+1;
1852                 } else {
1853                         d[byte_offset] |= (idx >> (bit_offset-2));
1854                         d[byte_offset+1] = 0;
1855                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1856                         n = byte_offset+2;
1857                 }
1858                 s++; i++;
1859         }
1860
1861         if (*s == '=') n -= 1;
1862
1863         /* fix up length */
1864         decoded.length = n;
1865         return decoded;
1866 }
1867
1868 /**
1869  * Decode a base64 string in-place - wrapper for the above
1870  **/
1871 void base64_decode_inplace(char *s)
1872 {
1873         DATA_BLOB decoded = base64_decode_data_blob(s);
1874         memcpy(s, decoded.data, decoded.length);
1875         /* null terminate */
1876         s[decoded.length] = '\0';
1877
1878         data_blob_free(&decoded);
1879 }
1880
1881 /**
1882  * Encode a base64 string into a malloc()ed string caller to free.
1883  *
1884  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1885  **/
1886 char * base64_encode_data_blob(DATA_BLOB data)
1887 {
1888         int bits = 0;
1889         int char_count = 0;
1890         size_t out_cnt = 0;
1891         size_t len = data.length;
1892         size_t output_len = data.length * 2;
1893         char *result = malloc(output_len); /* get us plenty of space */
1894
1895         while (len-- && out_cnt < (data.length * 2) - 5) {
1896                 int c = (unsigned char) *(data.data++);
1897                 bits += c;
1898                 char_count++;
1899                 if (char_count == 3) {
1900                         result[out_cnt++] = b64[bits >> 18];
1901                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1902                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1903             result[out_cnt++] = b64[bits & 0x3f];
1904             bits = 0;
1905             char_count = 0;
1906         } else {
1907             bits <<= 8;
1908         }
1909     }
1910     if (char_count != 0) {
1911         bits <<= 16 - (8 * char_count);
1912         result[out_cnt++] = b64[bits >> 18];
1913         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1914         if (char_count == 1) {
1915             result[out_cnt++] = '=';
1916             result[out_cnt++] = '=';
1917         } else {
1918             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1919             result[out_cnt++] = '=';
1920         }
1921     }
1922     result[out_cnt] = '\0';     /* terminate */
1923     return result;
1924 }
1925
1926 /* read a SMB_BIG_UINT from a string */
1927 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1928 {
1929
1930         SMB_BIG_UINT val = -1;
1931         const char *p = nptr;
1932         
1933         while (p && *p && isspace(*p))
1934                 p++;
1935 #ifdef LARGE_SMB_OFF_T
1936         sscanf(p,"%llu",&val);  
1937 #else /* LARGE_SMB_OFF_T */
1938         sscanf(p,"%lu",&val);
1939 #endif /* LARGE_SMB_OFF_T */
1940         if (entptr) {
1941                 while (p && *p && isdigit(*p))
1942                         p++;
1943                 *entptr = p;
1944         }
1945
1946         return val;
1947 }