]> git.samba.org - ira/wip.git/blob - source3/lib/util_str.c
Fix final valgrind errors with #830. Catch mb conversion error that may not
[ira/wip.git] / source3 / 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         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         size_t len;
1297
1298         /* this is quite a common operation, so we want it to be
1299            fast. We optimise for the ascii case, knowing that all our
1300            supported multi-byte character sets are ascii-compatible
1301            (ie. they match for the first 128 chars) */
1302
1303         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1304                 *s = tolower((unsigned char)*s);
1305                 s++;
1306         }
1307
1308         if (!*s)
1309                 return;
1310
1311         /* I assume that lowercased string takes the same number of bytes
1312          * as source string even in UTF-8 encoding. (VIV) */
1313         len = strlen(s) + 1;
1314         errno = 0;
1315         unix_strlower(s,len,s,len);     
1316         /* Catch mb conversion errors that may not terminate. */
1317         if (errno)
1318                 s[len-1] = '\0';
1319 }
1320
1321 /**
1322  Convert a string to upper case.
1323 **/
1324
1325 void strupper_m(char *s)
1326 {
1327         size_t len;
1328
1329         /* this is quite a common operation, so we want it to be
1330            fast. We optimise for the ascii case, knowing that all our
1331            supported multi-byte character sets are ascii-compatible
1332            (ie. they match for the first 128 chars) */
1333
1334         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1335                 *s = toupper((unsigned char)*s);
1336                 s++;
1337         }
1338
1339         if (!*s)
1340                 return;
1341
1342         /* I assume that lowercased string takes the same number of bytes
1343          * as source string even in multibyte encoding. (VIV) */
1344         len = strlen(s) + 1;
1345         errno = 0;
1346         unix_strupper(s,len,s,len);     
1347         /* Catch mb conversion errors that may not terminate. */
1348         if (errno)
1349                 s[len-1] = '\0';
1350 }
1351
1352 /**
1353  Return a RFC2254 binary string representation of a buffer.
1354  Used in LDAP filters.
1355  Caller must free.
1356 **/
1357
1358 char *binary_string(char *buf, int len)
1359 {
1360         char *s;
1361         int i, j;
1362         const char *hex = "0123456789ABCDEF";
1363         s = malloc(len * 3 + 1);
1364         if (!s)
1365                 return NULL;
1366         for (j=i=0;i<len;i++) {
1367                 s[j] = '\\';
1368                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1369                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1370                 j += 3;
1371         }
1372         s[j] = 0;
1373         return s;
1374 }
1375
1376 /**
1377  Just a typesafety wrapper for snprintf into a pstring.
1378 **/
1379
1380  int pstr_sprintf(pstring s, const char *fmt, ...)
1381 {
1382         va_list ap;
1383         int ret;
1384
1385         va_start(ap, fmt);
1386         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1387         va_end(ap);
1388         return ret;
1389 }
1390
1391
1392 /**
1393  Just a typesafety wrapper for snprintf into a fstring.
1394 **/
1395
1396 int fstr_sprintf(fstring s, const char *fmt, ...)
1397 {
1398         va_list ap;
1399         int ret;
1400
1401         va_start(ap, fmt);
1402         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1403         va_end(ap);
1404         return ret;
1405 }
1406
1407
1408 #ifndef HAVE_STRNDUP
1409 /**
1410  Some platforms don't have strndup.
1411 **/
1412
1413  char *strndup(const char *s, size_t n)
1414 {
1415         char *ret;
1416         
1417         n = strnlen(s, n);
1418         ret = malloc(n+1);
1419         if (!ret)
1420                 return NULL;
1421         memcpy(ret, s, n);
1422         ret[n] = 0;
1423
1424         return ret;
1425 }
1426 #endif
1427
1428 #ifndef HAVE_STRNLEN
1429 /**
1430  Some platforms don't have strnlen
1431 **/
1432
1433  size_t strnlen(const char *s, size_t n)
1434 {
1435         int i;
1436         for (i=0; s[i] && i<n; i++)
1437                 /* noop */ ;
1438         return i;
1439 }
1440 #endif
1441
1442 /**
1443  List of Strings manipulation functions
1444 **/
1445
1446 #define S_LIST_ABS 16 /* List Allocation Block Size */
1447
1448 char **str_list_make(const char *string, const char *sep)
1449 {
1450         char **list, **rlist;
1451         const char *str;
1452         char *s;
1453         int num, lsize;
1454         pstring tok;
1455         
1456         if (!string || !*string)
1457                 return NULL;
1458         s = strdup(string);
1459         if (!s) {
1460                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1461                 return NULL;
1462         }
1463         if (!sep) sep = LIST_SEP;
1464         
1465         num = lsize = 0;
1466         list = NULL;
1467         
1468         str = s;
1469         while (next_token(&str, tok, sep, sizeof(tok))) {               
1470                 if (num == lsize) {
1471                         lsize += S_LIST_ABS;
1472                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1473                         if (!rlist) {
1474                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1475                                 str_list_free(&list);
1476                                 SAFE_FREE(s);
1477                                 return NULL;
1478                         } else
1479                                 list = rlist;
1480                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1481                 }
1482                 
1483                 list[num] = strdup(tok);
1484                 if (!list[num]) {
1485                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1486                         str_list_free(&list);
1487                         SAFE_FREE(s);
1488                         return NULL;
1489                 }
1490         
1491                 num++;  
1492         }
1493         
1494         SAFE_FREE(s);
1495         return list;
1496 }
1497
1498 BOOL str_list_copy(char ***dest, const char **src)
1499 {
1500         char **list, **rlist;
1501         int num, lsize;
1502         
1503         *dest = NULL;
1504         if (!src)
1505                 return False;
1506         
1507         num = lsize = 0;
1508         list = NULL;
1509                 
1510         while (src[num]) {
1511                 if (num == lsize) {
1512                         lsize += S_LIST_ABS;
1513                         rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
1514                         if (!rlist) {
1515                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1516                                 str_list_free(&list);
1517                                 return False;
1518                         } else
1519                                 list = rlist;
1520                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1521                 }
1522                 
1523                 list[num] = strdup(src[num]);
1524                 if (!list[num]) {
1525                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1526                         str_list_free(&list);
1527                         return False;
1528                 }
1529
1530                 num++;
1531         }
1532         
1533         *dest = list;
1534         return True;    
1535 }
1536
1537 /**
1538  * Return true if all the elements of the list match exactly.
1539  **/
1540 BOOL str_list_compare(char **list1, char **list2)
1541 {
1542         int num;
1543         
1544         if (!list1 || !list2)
1545                 return (list1 == list2); 
1546         
1547         for (num = 0; list1[num]; num++) {
1548                 if (!list2[num])
1549                         return False;
1550                 if (!strcsequal(list1[num], list2[num]))
1551                         return False;
1552         }
1553         if (list2[num])
1554                 return False; /* if list2 has more elements than list1 fail */
1555         
1556         return True;
1557 }
1558
1559 void str_list_free(char ***list)
1560 {
1561         char **tlist;
1562         
1563         if (!list || !*list)
1564                 return;
1565         tlist = *list;
1566         for(; *tlist; tlist++)
1567                 SAFE_FREE(*tlist);
1568         SAFE_FREE(*list);
1569 }
1570
1571 /******************************************************************************
1572  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1573  for the work
1574  *****************************************************************************/
1575  
1576 BOOL str_list_sub_basic( char **list, const char *smb_name )
1577 {
1578         char *s, *tmpstr;
1579         
1580         while ( *list ) {
1581                 s = *list;
1582                 tmpstr = alloc_sub_basic(smb_name, s);
1583                 if ( !tmpstr ) {
1584                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1585                         return False;
1586                 }
1587
1588                 *list = tmpstr;
1589                         
1590                 list++;
1591         }
1592
1593         return True;
1594 }
1595
1596 /******************************************************************************
1597  substritute a specific pattern in a string list
1598  *****************************************************************************/
1599  
1600 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1601 {
1602         char *p, *s, *t;
1603         ssize_t ls, lp, li, ld, i, d;
1604
1605         if (!list)
1606                 return False;
1607         if (!pattern)
1608                 return False;
1609         if (!insert)
1610                 return False;
1611
1612         lp = (ssize_t)strlen(pattern);
1613         li = (ssize_t)strlen(insert);
1614         ld = li -lp;
1615                         
1616         while (*list) {
1617                 s = *list;
1618                 ls = (ssize_t)strlen(s);
1619
1620                 while ((p = strstr(s, pattern))) {
1621                         t = *list;
1622                         d = p -t;
1623                         if (ld) {
1624                                 t = (char *) malloc(ls +ld +1);
1625                                 if (!t) {
1626                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1627                                         return False;
1628                                 }
1629                                 memcpy(t, *list, d);
1630                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1631                                 SAFE_FREE(*list);
1632                                 *list = t;
1633                                 ls += ld;
1634                                 s = t +d +li;
1635                         }
1636                         
1637                         for (i = 0; i < li; i++) {
1638                                 switch (insert[i]) {
1639                                         case '`':
1640                                         case '"':
1641                                         case '\'':
1642                                         case ';':
1643                                         case '$':
1644                                         case '%':
1645                                         case '\r':
1646                                         case '\n':
1647                                                 t[d +i] = '_';
1648                                                 break;
1649                                         default:
1650                                                 t[d +i] = insert[i];
1651                                 }
1652                         }       
1653                 }
1654                 
1655                 
1656                 list++;
1657         }
1658         
1659         return True;
1660 }
1661
1662
1663 #define IPSTR_LIST_SEP  ","
1664 #define IPSTR_LIST_CHAR ','
1665
1666 /**
1667  * Add ip string representation to ipstr list. Used also
1668  * as part of @function ipstr_list_make
1669  *
1670  * @param ipstr_list pointer to string containing ip list;
1671  *        MUST BE already allocated and IS reallocated if necessary
1672  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1673  *        as a result of reallocation)
1674  * @param ip IP address which is to be added to list
1675  * @return pointer to string appended with new ip and possibly
1676  *         reallocated to new length
1677  **/
1678
1679 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1680 {
1681         char* new_ipstr = NULL;
1682         
1683         /* arguments checking */
1684         if (!ipstr_list || !service) return NULL;
1685
1686         /* attempt to convert ip to a string and append colon separator to it */
1687         if (*ipstr_list) {
1688                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1689                         inet_ntoa(service->ip), service->port);
1690                 SAFE_FREE(*ipstr_list);
1691         } else {
1692                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1693         }
1694         *ipstr_list = new_ipstr;
1695         return *ipstr_list;
1696 }
1697
1698
1699 /**
1700  * Allocate and initialise an ipstr list using ip adresses
1701  * passed as arguments.
1702  *
1703  * @param ipstr_list pointer to string meant to be allocated and set
1704  * @param ip_list array of ip addresses to place in the list
1705  * @param ip_count number of addresses stored in ip_list
1706  * @return pointer to allocated ip string
1707  **/
1708  
1709 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
1710 {
1711         int i;
1712         
1713         /* arguments checking */
1714         if (!ip_list && !ipstr_list) return 0;
1715
1716         *ipstr_list = NULL;
1717         
1718         /* process ip addresses given as arguments */
1719         for (i = 0; i < ip_count; i++)
1720                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1721         
1722         return (*ipstr_list);
1723 }
1724
1725
1726 /**
1727  * Parse given ip string list into array of ip addresses
1728  * (as ip_service structures)  
1729  *    e.g. 192.168.1.100:389,192.168.1.78, ...
1730  *
1731  * @param ipstr ip string list to be parsed 
1732  * @param ip_list pointer to array of ip addresses which is
1733  *        allocated by this function and must be freed by caller
1734  * @return number of succesfully parsed addresses
1735  **/
1736  
1737 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
1738 {
1739         fstring token_str;
1740         size_t count;
1741         int i;
1742
1743         if (!ipstr_list || !ip_list) 
1744                 return 0;
1745         
1746         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1747         if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
1748                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
1749                 return 0;
1750         }
1751         
1752         for ( i=0; 
1753                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
1754                 i++ ) 
1755         {
1756                 struct in_addr addr;
1757                 unsigned port = 0;      
1758                 char *p = strchr(token_str, ':');
1759                 
1760                 if (p) {
1761                         *p = 0;
1762                         port = atoi(p+1);
1763                 }
1764
1765                 /* convert single token to ip address */
1766                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
1767                         break;
1768                                 
1769                 (*ip_list)[i].ip = addr;
1770                 (*ip_list)[i].port = port;
1771         }
1772         
1773         return count;
1774 }
1775
1776
1777 /**
1778  * Safely free ip string list
1779  *
1780  * @param ipstr_list ip string list to be freed
1781  **/
1782
1783 void ipstr_list_free(char* ipstr_list)
1784 {
1785         SAFE_FREE(ipstr_list);
1786 }
1787
1788
1789 /**
1790  Unescape a URL encoded string, in place.
1791 **/
1792
1793 void rfc1738_unescape(char *buf)
1794 {
1795         char *p=buf;
1796
1797         while (p && *p && (p=strchr_m(p,'%'))) {
1798                 int c1 = p[1];
1799                 int c2 = p[2];
1800
1801                 if (c1 >= '0' && c1 <= '9')
1802                         c1 = c1 - '0';
1803                 else if (c1 >= 'A' && c1 <= 'F')
1804                         c1 = 10 + c1 - 'A';
1805                 else if (c1 >= 'a' && c1 <= 'f')
1806                         c1 = 10 + c1 - 'a';
1807                 else {p++; continue;}
1808
1809                 if (c2 >= '0' && c2 <= '9')
1810                         c2 = c2 - '0';
1811                 else if (c2 >= 'A' && c2 <= 'F')
1812                         c2 = 10 + c2 - 'A';
1813                 else if (c2 >= 'a' && c2 <= 'f')
1814                         c2 = 10 + c2 - 'a';
1815                 else {p++; continue;}
1816                         
1817                 *p = (c1<<4) | c2;
1818
1819                 memmove(p+1, p+3, strlen(p+3)+1);
1820                 p++;
1821         }
1822 }
1823
1824 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1825
1826 /**
1827  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1828  **/
1829 DATA_BLOB base64_decode_data_blob(const char *s)
1830 {
1831         int bit_offset, byte_offset, idx, i, n;
1832         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1833         unsigned char *d = decoded.data;
1834         char *p;
1835
1836         n=i=0;
1837
1838         while (*s && (p=strchr_m(b64,*s))) {
1839                 idx = (int)(p - b64);
1840                 byte_offset = (i*6)/8;
1841                 bit_offset = (i*6)%8;
1842                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1843                 if (bit_offset < 3) {
1844                         d[byte_offset] |= (idx << (2-bit_offset));
1845                         n = byte_offset+1;
1846                 } else {
1847                         d[byte_offset] |= (idx >> (bit_offset-2));
1848                         d[byte_offset+1] = 0;
1849                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1850                         n = byte_offset+2;
1851                 }
1852                 s++; i++;
1853         }
1854
1855         if (*s == '=') n -= 1;
1856
1857         /* fix up length */
1858         decoded.length = n;
1859         return decoded;
1860 }
1861
1862 /**
1863  * Decode a base64 string in-place - wrapper for the above
1864  **/
1865 void base64_decode_inplace(char *s)
1866 {
1867         DATA_BLOB decoded = base64_decode_data_blob(s);
1868         memcpy(s, decoded.data, decoded.length);
1869         /* null terminate */
1870         s[decoded.length] = '\0';
1871
1872         data_blob_free(&decoded);
1873 }
1874
1875 /**
1876  * Encode a base64 string into a malloc()ed string caller to free.
1877  *
1878  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
1879  **/
1880 char * base64_encode_data_blob(DATA_BLOB data)
1881 {
1882         int bits = 0;
1883         int char_count = 0;
1884         size_t out_cnt = 0;
1885         size_t len = data.length;
1886         size_t output_len = data.length * 2;
1887         char *result = malloc(output_len); /* get us plenty of space */
1888
1889         while (len-- && out_cnt < (data.length * 2) - 5) {
1890                 int c = (unsigned char) *(data.data++);
1891                 bits += c;
1892                 char_count++;
1893                 if (char_count == 3) {
1894                         result[out_cnt++] = b64[bits >> 18];
1895                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1896                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1897             result[out_cnt++] = b64[bits & 0x3f];
1898             bits = 0;
1899             char_count = 0;
1900         } else {
1901             bits <<= 8;
1902         }
1903     }
1904     if (char_count != 0) {
1905         bits <<= 16 - (8 * char_count);
1906         result[out_cnt++] = b64[bits >> 18];
1907         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1908         if (char_count == 1) {
1909             result[out_cnt++] = '=';
1910             result[out_cnt++] = '=';
1911         } else {
1912             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1913             result[out_cnt++] = '=';
1914         }
1915     }
1916     result[out_cnt] = '\0';     /* terminate */
1917     return result;
1918 }
1919
1920 /* read a SMB_BIG_UINT from a string */
1921 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1922 {
1923
1924         SMB_BIG_UINT val = -1;
1925         const char *p = nptr;
1926         
1927         while (p && *p && isspace(*p))
1928                 p++;
1929 #ifdef LARGE_SMB_OFF_T
1930         sscanf(p,"%llu",&val);  
1931 #else /* LARGE_SMB_OFF_T */
1932         sscanf(p,"%lu",&val);
1933 #endif /* LARGE_SMB_OFF_T */
1934         if (entptr) {
1935                 while (p && *p && isdigit(*p))
1936                         p++;
1937                 *entptr = p;
1938         }
1939
1940         return val;
1941 }