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 **/
38BOOL 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/**
80This is like next_token but is not re-entrant and "remembers" the first
81parameter so you can pass NULL. This is useful for user interface code
82but beware the fact that it is not re-entrant!
83**/
84
85static const char *last_ptr=NULL;
86
87BOOL 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
98static uint16 tmpbuf[sizeof(pstring)];
99
100void 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
110char **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 **/
180int 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**/
236int 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 **/
249BOOL 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 **/
264BOOL 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
278BOOL 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/**
289Do a case-insensitive, whitespace-ignoring string compare.
290**/
291
292int 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
323char *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
337void 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
350BOOL 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
365void 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
398char *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
411size_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
424size_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
431BOOL 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
488BOOL 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
528BOOL 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
542BOOL 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
556size_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
572char *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**/
608char *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**/
648char *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**/
690char *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
723static 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
755size_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
794void 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
810BOOL 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 */
831static char *null_string = NULL;
832
833/**
834 Set a string value, allocing the space for the string
835**/
836
837static 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
868void 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
882BOOL 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
900void 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
946void fstring_sub(char *s,const char *pattern,const char *insert)
947{
948	string_sub(s, pattern, insert, sizeof(fstring));
949}
950
951void 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
963char *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
1030void 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
1071static 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
1117smb_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
1134static 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
1159const 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
1173char *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
1185char *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
1219char *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
1275char *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
1294void 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
1325void 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
1358char *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
1396int 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
1448char **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
1498BOOL 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 **/
1540BOOL 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
1559void 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
1576BOOL 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
1600BOOL 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
1679char* 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
1709char* 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
1737int 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
1783void 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
1793void 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
1824static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1825
1826/**
1827 * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1828 **/
1829DATA_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 **/
1865void 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 **/
1880char * 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 */
1921SMB_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}
1942