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