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